You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Room唯一约束未生效:重复id_from_client可插入

Room唯一索引未生效问题排查

你定义了如下ActivityDAO和Activity实体,为id_from_client字段设置了唯一索引,但插入相同id_from_client的对象时并未触发约束,反而新增了行。导出数据库后发现生成的唯一索引语句是CREATE UNIQUE INDEX index_Activity_id_id_from_client ON Activity (id, id_from_client),而非仅针对id_from_client的索引。

原ActivityDAO代码

@Dao
public interface ActivityDAO {
    @Insert
    void insert(Activity activity);
}

原Activity实体代码

@Entity(indices = {@Index(value = {"`id_from_client`"},
        unique = true)})
public class Activity {
    @PrimaryKey(autoGenerate = true)
    public int id;

    @NotNull
    @ColumnInfo(name = "id_from_client")
    public String id_from_client;
}

问题原因

问题出在@Index注解的value参数中——你用反引号包裹了id_from_client字段名,Room在解析这个配置时出现错误,误将带反引号的字段名识别为需要和主键id组合的复合索引,最终生成了包含id和id_from_client的复合唯一索引。由于主键id是自增的,每次插入的id都不同,所以复合索引不会触发唯一约束。

解决方法

去掉@Index中id_from_client的反引号,修改后的Activity实体定义如下:

@Entity(indices = {@Index(value = {"id_from_client"},
        unique = true)})
public class Activity {
    @PrimaryKey(autoGenerate = true)
    public int id;

    @NotNull
    @ColumnInfo(name = "id_from_client")
    public String id_from_client;
}

修改后重新编译项目,Room会生成正确的唯一索引语句:

CREATE UNIQUE INDEX index_Activity_id_from_client ON Activity (id_from_client)

此时插入重复id_from_client的记录,SQLite会触发唯一约束,抛出SQLiteConstraintException,阻止重复数据插入。

内容的提问来源于stack exchange,提问作者Clement Osumo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 00:10:32