Room数据库调用insertAll批量插入用户仅成功写入第一条如何解决
Room批量插入仅第一条数据入库问题修复
问题根因
出现这个问题核心是两个原因:
- 插入数据触发唯一键冲突,Room默认
@Insert的冲突策略是ABORT,遇到第一条冲突数据就会终止后续所有插入操作,且你在子线程中没有捕获异常,看不到报错日志,表现为只有第一条数据入库。从你贴的构造参数看,user1和user2的第二个字段值均为"rrr",如果该字段被设置为主键或唯一索引,就会触发这个问题。 - DAO层
insertAll方法定义不规范、单例初始化逻辑有隐患,导致数据库操作异常中断。
修复步骤
- 第一步:核对实体类约束
打开User实体类,检查所有被@PrimaryKey、@Index(unique = true)标记的字段,确认待插入的3条数据对应字段没有重复值。 - 第二步:修改插入方法的冲突策略
打开UserDAO接口,修改insertAll方法的@Insert注解,指定冲突时替换旧数据,避免插入中断:@Insert(onConflict = OnConflictStrategy.REPLACE) void insertAll(User[] users); - 第三步:添加异常捕获确认插入状态
你当前的数据库操作没有加异常捕获,出错时没有任何日志,修改addUsers方法:public void addUsers(User[] s) { Log.d("main_activity_uid", "开始插入,待插入数量:" + s.length); try { userDAOs.userDAO().insertAll(s); user_list.addAll(Arrays.asList(s)); Log.d("main_activity_uid", "插入完成"); } catch (Exception e) { Log.e("main_activity_uid", "插入数据库失败", e); } } - 第四步:修复单例类的初始化隐患
你当前的单例类存在无参getInstance方法,调用该方法不会初始化userDAOs,后续容易触发空指针,直接删除无参的getInstance方法,修改带Context的初始化逻辑,用Application Context避免内存泄漏:public static synchronized Model_user getInstance(Context c) { if (theinstance == null) { Context appContext = c.getApplicationContext(); userDAOs = Room.databaseBuilder(appContext, AppDatabase.class, "userdb").build(); theinstance = new Model_user(); } return theinstance; }
修改完成后重新运行即可实现3条数据全部批量入库,如果还有报错,看catch块打出来的异常日志定位具体约束冲突点即可。
内容的提问来源于stack exchange,提问作者Elly
相关产品推荐
相关产品推荐

