Realm存储Retrofit获取的Post数据报错,需避免重复存储求解决方案
解决Realm存储主键相关报错及冗余问题
嘿,我来帮你搞定这个Realm存储的问题!咱们一步步来分析和解决:
先搞懂你遇到的两个错误原因
第一个错误
'Post' has a primary key, use 'createObject(Class, Object)' instead.
因为你的Post类加了@PrimaryKey注解,Realm规定创建带主键的对象时,必须在createObject方法里指定主键的值,不能用无参的创建方式。第二个错误
"Primary key value is not a long"
你修改后传了p(整个Post对象)给createObject的第二个参数,但这个参数需要的是主键的具体值(也就是你的long类型的id),不是整个实体对象,所以Realm识别不了类型,报错了。
两种正确的解决方案(还能解决重复存储的冗余问题)
方案一:手动判断+createObject(适合需要自定义逻辑的场景)
先查询数据库中是否存在该主键的记录,不存在就创建(传入主键值),存在就更新数据:
private void save_to_database(final Post p) { realm.executeTransactionAsync(new Realm.Transaction() { @Override public void execute(Realm realm) { // 查询是否已有该id的记录 Post existingPost = realm.where(Post.class) .equalTo("id", p.getId()) .findFirst(); if(existingPost == null) { // 不存在则创建,第二个参数传主键值p.getId() Post post = realm.createObject(Post.class, p.getId()); post.setUserId(p.getUserId()); post.setTitle(p.getTitle()); post.setBody(p.getBody()); } else { // 存在则更新字段 existingPost.setUserId(p.getUserId()); existingPost.setTitle(p.getTitle()); existingPost.setBody(p.getBody()); } } }); }
方案二:用copyToRealmOrUpdate(推荐,简洁自动处理增改)
Realm提供了copyToRealmOrUpdate方法,它会自动根据主键判断:如果数据库中已有该主键的记录,就更新数据;如果没有,就插入新记录,完美解决重复存储的问题:
private void save_to_database(final Post p) { realm.executeTransactionAsync(new Realm.Transaction() { @Override public void execute(Realm realm) { // 直接传入对象,Realm自动处理增改 realm.copyToRealmOrUpdate(p); } }); }
额外提醒
用copyToRealmOrUpdate的时候,要确保你的Post对象的主键字段(也就是id)已经正确赋值,这样Realm才能准确判断是新增还是更新。
内容的提问来源于stack exchange,提问作者Sudeep
相关产品推荐
相关产品推荐

