【问题标题】:Getting UNIQUE constraint failed: tbl_data.id (Sqlite code 1555 SQLITE_CONSTRAINT_PRIMARYKEY) error in android studio room获取 UNIQUE 约束失败:android studio 中的 tbl_data.id(Sqlite 代码 1555 SQLITE_CONSTRAINT_PRIMARYKEY)错误
【发布时间】:2021-12-20 13:27:30
【问题描述】:

当我将 id 初始化为主键并添加了唯一属性时出现此错误。

数据类代码:

    @Entity(tableName = "tbl_data" , indices = {@Index(value = {"id"},
    unique = true)})
    public class Data {
    @PrimaryKey
    private Integer id ;
    private Integer year;
    private Double dowry;

public Data(Integer id,Integer year, Double dowry) {
    this.id = id;
    this.year = year;
    this.dowry = dowry;
}

public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

public int getYear() {
    return year;
}
public void setYear(int year) {
    this.year = year;
}
public Double getDowry() {
    return dowry;
}
public void setDowry(Double dowry) {
    this.dowry = dowry;
}

数据库类代码:

@Database(version = 1 , exportSchema = false , entities = {Data.class} )
public abstract class AppDatabase extends RoomDatabase {
private static AppDatabase appDatabase;

public static AppDatabase getAppDatabase(Context context) {
    if (appDatabase == null)
        appDatabase = Room.databaseBuilder(context.getApplicationContext(),
AppDatabase.class,
                "db_app")
                .allowMainThreadQueries().fallbackToDestructiveMigration()
                .build();
        return appDatabase;
    }

    public abstract DataDao getDataDao();
}

和主要活动代码:

    db = AppDatabase.getAppDatabase(this);
    dataDao = db.getDataDao();

    dataDao.insertC(new Data(1,1315, 0.004 ), new Data(2,1316, 0.005), new Data(3,1317,  0.006), new Data(4,1318, 0.007));

logat 完全错误:

2021-11-07 12:20:45.070 24994-24994/com.mohajer.kitset2 E/AndroidRuntime: 致命异常: main 进程:com.mohajer.kitset2,PID:24994 java.lang.RuntimeException:无法启动活动 ComponentInfo{com.mohajer.kitset2/com.mohajer.kitset2.MainActivity}:android.database.sqlite.SQLiteConstraintException:唯一约束失败:tbl_data.id(Sqlite 代码 1555 SQLITE_CONSTRAINT_PRIMARYKEY),(操作系统错误 - 2:没有这样的文件或目录) 在 android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3430) 在 android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3614) 在 android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:86) 在 android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 在 android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:2199) 在 android.os.Handler.dispatchMessage(Handler.java:112) 在 android.os.Looper.loop(Looper.java:216) 在 android.app.ActivityThread.main(ActivityThread.java:7625) 在 java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987) 引起:android.database.sqlite.SQLiteConstraintException:唯一约束失败:tbl_data.id(Sqlite 代码 1555 SQLITE_CONSTRAINT_PRIMARYKEY),(操作系统错误 - 2:没有这样的文件或目录) 在 android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(本机方法) 在 android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:841) 在 android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:803) 在 android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86) 在 androidx.sqlite.db.framework.FrameworkSQLiteStatement.executeInsert(FrameworkSQLiteStatement.java:51) 在 androidx.room.EntityInsertionAdapter.insertAndReturnIdsArrayBox(EntityInsertionAdapter.java:199) 在 com.mohajer.kitset2.DataDao_Impl.insertC(DataDao_Impl.java:50) 在 com.mohajer.kitset2.MainActivity.onCreate(MainActivity.java:36) 在 android.app.Activity.performCreate(Activity.java:7458) 在 android.app.Activity.performCreate(Activity.java:7448) 在 android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1286) 在 android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3409) 在 android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3614) 在 android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:86) 在 android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 在 android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:2199) 在 android.os.Handler.dispatchMessage(Handler.java:112) 在 android.os.Looper.loop(Looper.java:216) 在 android.app.ActivityThread.main(ActivityThread.java:7625) 在 java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)

【问题讨论】:

    标签: java android sql android-studio android-room


    【解决方案1】:

    使用 @PrimaryKey 意味着一个 UNIQUE 约束,因此不需要在 id 列上使用唯一索引(索引只是浪费)。

    在插入时使用 id 值对插入进行硬编码(没有忽略冲突的 onConflict 约束)将在从全新安装运行一次(重新运行)后导致 UNIQUE 冲突作为 id 的 1、2、3 和4 个已经存在。

    将@Dao 编码为@Insert(onConflict = OnConflictStrategy.IGNORE) 将忽略冲突而不会失败并且不会插入重复项。

    【讨论】:

    • 再次感谢您的帮助和您回答我问题的时间。我添加了 @Insert(onConflict = OnConflictStrategy.IGNORE) 并且它有效。但我起初我让 id 自动生成,它再次提示重复的行。所以我删除了该行并再次对其进行硬编码它可以工作,并且该表不再有重复的行并且它没有再次崩溃。
    • 我还有一个问题,我可以将年份设置为主键吗?提示当我在年份之前放置注释时,我在 Logcat 中收到错误,我什至没有在这个应用程序中使用 id,并且年份的值是唯一的
    • @danimohajer 是的,您可以将年份设置为主键。您也可以没有 id 列。您不能将@PrimaryKey 编码两次(如果您想要一个复合主键,您可以使用 primarykeys 参数(类似于 indicies))。请注意,在您进行更改之后,您应该卸载应用程序(删除数据库以便重新创建数据库)或增加@Database 中的版本号(.fallBackToDestructiveMigrattion 将有效地删除数据库并将再次创建)。
    • 就这么做了,效果很好,效果很好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-18
    • 2018-07-26
    • 2016-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多