微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

房间检查约束失败:车辆Sqlite 代码 275 SQLITE_CONSTRAINT_CHECK操作系统错误 - 11

如何解决房间检查约束失败:车辆Sqlite 代码 275 SQLITE_CONSTRAINT_CHECK操作系统错误 - 11

我被这个问题困扰了好几个小时……我得到了一个简单的实体类

@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 举报,一经查实,本站将立刻删除。