问题描述
@Entity(tableName = "Vehicle",indices = {@Index(value = {"vehicleName"},unique = true),@Index(value = {"brandId"}),@Index(value = {"ownerId"})},foreignKeys = {@ForeignKey(entity=Brand.class,parentColumns="id",childColumns="brandId",onDelete = SET_DEFAULT),@ForeignKey(entity=Driver.class,childColumns="ownerId",}
)
public class Vehicle implements Parcelable {
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "id")
@NotNull
private int id;
@ColumnInfo(name = "vehicleType")
@TypeConverters(Converters.class)
@NotNull
private VehicleType vehicleType;
@ColumnInfo(name = "vehicleName")
@NotNull
private String vehicleName;
@ColumnInfo(name = "distanceUnit")
@TypeConverters(Converters.class)
@NotNull
private distanceUnit distanceUnit;
@ColumnInfo(name = "currencyUnit")
@TypeConverters(Converters.class)
@NotNull
private Currency currencyUnit;
@ColumnInfo(name = "mainFuelTank")
@TypeConverters(Converters.class)
@NotNull
private FuelTank mainFuelTank;
@ColumnInfo(name = "secondFuelTank")
@TypeConverters(Converters.class)
private FuelTank secondFuelTank;
@ColumnInfo(name = "vehiclePic")
private String vehiclePic;
@ColumnInfo(name = "brandId")
private int brandId;
@ColumnInfo(name = "modelName")
private String modelName;
@ColumnInfo(name = "buildYear")
@TypeConverters(Converters.class)
private Date buildYear;
@ColumnInfo(name = "ownerId")
private int ownerId;
@ColumnInfo(name = "licensePlate")
private String licensePlate;
@ColumnInfo(name = "vinNumber")
private String vinNumber;
@ColumnInfo(name = "note")
private String note;
@ColumnInfo(name = "isActive",defaultValue = "1")
@NotNull
private boolean isActive;
@ColumnInfo(name = "customVehicleProps")
@TypeConverters(Converters.class)
private Map<String,String> customVehicleProps;
public Vehicle(VehicleType vehicleType,@NotNull String vehicleName,@NotNull distanceUnit distanceUnit,@NotNull Currency currencyUnit,@NotNull FuelTank mainFuelTank) {
this.vehicleType = vehicleType;
this.vehicleName = vehicleName;
this.distanceUnit = distanceUnit;
this.currencyUnit = currencyUnit;
this.mainFuelTank = mainFuelTank;
customVehicleProps = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
setIsActive(true);
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public VehicleType getVehicleType() {
return vehicleType;
}
public void setVehicleType(VehicleType vehicleType) {
this.vehicleType = vehicleType;
}
@NotNull
public String getVehicleName() {
return vehicleName;
}
public void setVehicleName(@NotNull String vehicleName) {
this.vehicleName = vehicleName;
}
@NotNull
public distanceUnit getdistanceUnit() {
return distanceUnit;
}
public void setdistanceUnit(@NotNull distanceUnit distanceUnit) {
this.distanceUnit = distanceUnit;
}
@NotNull
public Currency getCurrencyUnit() {
return currencyUnit;
}
public void setCurrencyUnit(@NotNull Currency currencyUnit) {
this.currencyUnit = currencyUnit;
}
@NotNull
public FuelTank getMainFuelTank() {
return mainFuelTank;
}
public void setMainFuelTank(@NotNull FuelTank mainFuelTank) {
this.mainFuelTank = mainFuelTank;
}
public FuelTank getSecondFuelTank() {
return secondFuelTank;
}
public void setSecondFuelTank(FuelTank secondFuelTank) {
this.secondFuelTank = secondFuelTank;
}
public String getVehiclePic() {
return vehiclePic;
}
public void setVehiclePic(String vehiclePic) {
this.vehiclePic = vehiclePic;
}
public int getBrandId() {
return brandId;
}
public void setBrandId(int brandId) {
this.brandId = brandId;
}
public String getModelName() {
return modelName;
}
public void setModelName(String modelName) {
this.modelName = modelName;
}
public Date getBuildYear() {
return buildYear;
}
public void setBuildYear(Date buildYear) {
this.buildYear = buildYear;
}
public int getownerId() {
return ownerId;
}
public void setownerId(int ownerId) {
this.ownerId = ownerId;
}
public String getLicensePlate() {
return licensePlate;
}
public void setLicensePlate(String licensePlate) {
this.licensePlate = licensePlate;
}
public String getVinNumber() {
return vinNumber;
}
public void setVinNumber(String vinNumber) {
this.vinNumber = vinNumber;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
public boolean getIsActive() {
return isActive;
}
public void setIsActive(boolean isActive) {
this.isActive = isActive;
}
public Map<String,String> getCustomVehicleProps() {
return customVehicleProps;
}
public void setCustomVehicleProps(Map<String,String> customVehicleProps) {
this.customVehicleProps = customVehicleProps;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Vehicle vehicle = (Vehicle) o;
return getId() == vehicle.getId();
}
@Override
public int hashCode() {
return Objects.hash(getId());
}
public void addCustomProperty(String key,String prop){
customVehicleProps.put(key,prop);
}
public void removeCustomProperty(String key){
customVehicleProps.remove(key);
}
@Override
public String toString() {
return "Vehicle{" +
"id=" + id +
",vehicleType=" + vehicleType +
",vehicleName='" + vehicleName + '\'' +
",distanceUnit=" + distanceUnit +
",currencyUnit=" + currencyUnit +
",mainFuelTank=" + mainFuelTank +
",secondFuelTank=" + secondFuelTank +
",vehiclePic='" + vehiclePic + '\'' +
",brandId=" + brandId +
",modelName='" + modelName + '\'' +
",buildYear=" + buildYear +
",ownerId=" + ownerId +
",licensePlate='" + licensePlate + '\'' +
",vinNumber='" + vinNumber + '\'' +
",note='" + note + '\'' +
",isActive=" + isActive +
",customVehicleProps=" + customVehicleProps +
'}';
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writetoParcel(Parcel dest,int flags) {
dest.writeInt(this.id);
dest.writeInt(this.vehicleType == null ? -1 : this.vehicleType.ordinal());
dest.writeString(this.vehicleName);
dest.writeInt(this.distanceUnit == null ? -1 : this.distanceUnit.ordinal());
dest.writeSerializable(this.currencyUnit);
dest.writeParcelable(this.mainFuelTank,flags);
dest.writeParcelable(this.secondFuelTank,flags);
dest.writeString(this.vehiclePic);
dest.writeInt(this.brandId);
dest.writeString(this.modelName);
dest.writeLong(this.buildYear != null ? this.buildYear.getTime() : -1);
dest.writeInt(this.ownerId);
dest.writeString(this.licensePlate);
dest.writeString(this.vinNumber);
dest.writeString(this.note);
dest.writeByte(this.isActive ? (byte) 1 : (byte) 0);
dest.writeInt(this.customVehicleProps.size());
for (Map.Entry<String,String> entry : this.customVehicleProps.entrySet()) {
dest.writeString(entry.getKey());
dest.writeString(entry.getValue());
}
}
public void readFromParcel(Parcel source) {
this.id = source.readInt();
int tmpVehicleType = source.readInt();
this.vehicleType = tmpVehicleType == -1 ? null : VehicleType.values()[tmpVehicleType];
this.vehicleName = source.readString();
int tmpdistanceUnit = source.readInt();
this.distanceUnit = tmpdistanceUnit == -1 ? null : distanceUnit.values()[tmpdistanceUnit];
this.currencyUnit = (Currency) source.readSerializable();
this.mainFuelTank = source.readParcelable(FuelTank.class.getClassLoader());
this.secondFuelTank = source.readParcelable(FuelTank.class.getClassLoader());
this.vehiclePic = source.readString();
this.brandId = source.readInt();
this.modelName = source.readString();
long tmpBuildYear = source.readLong();
this.buildYear = tmpBuildYear == -1 ? null : new Date(tmpBuildYear);
this.ownerId = source.readInt();
this.licensePlate = source.readString();
this.vinNumber = source.readString();
this.note = source.readString();
this.isActive = source.readByte() != 0;
int customVehiclePropsSize = source.readInt();
this.customVehicleProps = new HashMap<String,String>(customVehiclePropsSize);
for (int i = 0; i < customVehiclePropsSize; i++) {
String key = source.readString();
String value = source.readString();
this.customVehicleProps.put(key,value);
}
}
protected Vehicle(Parcel in) {
this.id = in.readInt();
int tmpVehicleType = in.readInt();
this.vehicleType = tmpVehicleType == -1 ? null : VehicleType.values()[tmpVehicleType];
this.vehicleName = in.readString();
int tmpdistanceUnit = in.readInt();
this.distanceUnit = tmpdistanceUnit == -1 ? null : distanceUnit.values()[tmpdistanceUnit];
this.currencyUnit = (Currency) in.readSerializable();
this.mainFuelTank = in.readParcelable(FuelTank.class.getClassLoader());
this.secondFuelTank = in.readParcelable(FuelTank.class.getClassLoader());
this.vehiclePic = in.readString();
this.brandId = in.readInt();
this.modelName = in.readString();
long tmpBuildYear = in.readLong();
this.buildYear = tmpBuildYear == -1 ? null : new Date(tmpBuildYear);
this.ownerId = in.readInt();
this.licensePlate = in.readString();
this.vinNumber = in.readString();
this.note = in.readString();
this.isActive = in.readByte() != 0;
int customVehiclePropsSize = in.readInt();
this.customVehicleProps = new HashMap<String,String>(customVehiclePropsSize);
for (int i = 0; i < customVehiclePropsSize; i++) {
String key = in.readString();
String value = in.readString();
this.customVehicleProps.put(key,value);
}
}
public static final Parcelable.Creator<Vehicle> CREATOR = new Parcelable.Creator<Vehicle>() {
@Override
public Vehicle createFromParcel(Parcel source) {
return new Vehicle(source);
}
@Override
public Vehicle[] newArray(int size) {
return new Vehicle[size];
}
};
}
对应的迁移代码:
database.execsql("DROP TABLE IF EXISTS Vehicle");
database.execsql("CREATE TABLE IF NOT EXISTS Vehicle(" +
"id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," +
"vehicleName TEXT UNIQUE NOT NULL," +
"distanceUnit TEXT NOT NULL CHECK(distanceUnit = \"KM\" or distanceUnit = \"MILES\")," +
"currencyUnit TEXT NOT NULL," +
"mainFuelTank TEXT NOT NULL," +
"secondFuelTank TEXT," +
"vehiclePic TEXT," +
"modelName TEXT," +
"licensePlate TEXT," +
"vinNumber TEXT," +
"note TEXT," +
"isActive INTEGER NOT NULL DEFAULT 1 CHECK(isActive IN (0,1))," +
"customVehicleProps TEXT," +
"buildYear INTEGER," +
"ownerId INTEGER NOT NULL," +
"brandId INTEGER NOT NULL," +
"vehicleType TEXT NOT NULL CHECK(vehicleType = \"MOTORCYCLE\" or vehicleType = \"CAR\" or vehicleType = \"TRUCK\" or vehicleType = \"BUS\")," +
"FOREIGN KEY(\"ownerId\") REFERENCES \"Driver\"(\"id\") ON DELETE SET DEFAULT,"+
"FOREIGN KEY(\"brandId\") REFERENCES \"Brand\"(\"id\") ON DELETE SET DEFAULT)");
尽你所能,我有 2-3 个检查约束不允许虚拟值。 但是如果我尝试添加一个具有正确属性的对象。 例如
Vehicle{id=0,vehicleType=CAR,vehicleName='Audi',distanceUnit=KM,currencyUnit=NAD,mainFuelTank=FuelTank{fuelType=LIQUIDS,maxFuelAmount=50.0,volumeUnit=LITER},secondFuelTank=null,vehiclePic='null',brandId=1,modelName='',buildYear=null,ownerId=1,licensePlate='',vinNumber='',note='',isActive=true,customVehicleProps={=}}
我收到一个 CONSTRAINT 错误,这对我没有任何意义,导致 distanceUnit、isActive、 VehicleType 是正确的约束,主键也是自动增量,所以我不应该担心。 问题是什么? 我确保我拥有用于距离单位和车辆类型的 ENUMS 的每个转换器类。
android.database.sqlite.sqliteConstraintException: CHECK constraint Failed: Vehicle (sqlite code 275 sqlITE_CONSTRAINT_CHECK),(OS error - 11:Try again)
at android.database.sqlite.sqliteConnection.nativeExecuteForLastInsertedRowId(Native Method)
at android.database.sqlite.sqliteConnection.executeForLastInsertedRowId(sqliteConnection.java:923)
at android.database.sqlite.sqliteSession.executeForLastInsertedRowId(sqliteSession.java:810)
at android.database.sqlite.sqliteStatement.executeInsert(sqliteStatement.java:88)
at androidx.sqlite.db.framework.FrameworksqliteStatement.executeInsert(FrameworksqliteStatement.java:51)
at androidx.room.EntityInsertionAdapter.insertAndReturnId(EntityInsertionAdapter.java:114)
at com.example.dochjavatestimplementation.pkgBAO.CarServiceDao_CarServiceDB_Impl$18.call(CarServiceDao_CarServiceDB_Impl.java:543)
at com.example.dochjavatestimplementation.pkgBAO.CarServiceDao_CarServiceDB_Impl$18.call(CarServiceDao_CarServiceDB_Impl.java:538)
at io.reactivex.internal.operators.single.SingleFromCallable.subscribeActual(SingleFromCallable.java:44)
at io.reactivex.Single.subscribe(Single.java:3603)
at io.reactivex.internal.operators.single.SingleSubscribeOn$SubscribeOnObserver.run(SingleSubscribeOn.java:89)
at io.reactivex.Scheduler$disposeTask.run(Scheduler.java:578)
at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:66)
at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:57)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:929)
我的转换器如下所示:
@TypeConverter
public static distanceUnit fromStringTodistanceUnit(String value) {
Type listType = new Typetoken<distanceUnit>() {}.getType();
return gson.fromJson(value,listType);
}
@TypeConverter
public static String fromdistanceUnitToString(distanceUnit dUnit) {
return dUnit.toString();
}
@TypeConverter
public static VehicleType fromStringToVehicleType(String value) {
Type listType = new Typetoken<VehicleType>() {}.getType();
return gson.fromJson(value,listType);
}
@TypeConverter
public static String fromVehicleTypetoString(VehicleType vt) {
return gson.toJson(vt);
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)