Realm数据库数据保存异常:Account.accessToken关联对象为空
问题分析与解决方案
这个问题的核心原因大概率是你传入的Account对象不是Realm的「托管对象」,或者你后续用来检查结果的Account实例不是从Realm中重新查询的托管对象,导致关联的AccessToken没有被正确持久化或更新。
具体问题拆解
- 非托管对象的属性修改无法被Realm追踪:如果你的
account参数是通过new Account()创建的,或是从Realm缓存/外部传入的未被Realm管理的对象,那么在事务中调用account.setAccessToken(accessToken)时,Realm无法感知到这个修改,自然不会将关联关系持久化。 - set方法返回值不影响逻辑,但对象托管状态是关键:你的
Account.setAccessToken方法返回赋值后的对象,这本身没问题,但核心还是要确保操作的对象处于Realm的管理之下。
针对性解决方案
根据你的使用场景,分两种情况处理:
情况1:传入的Account已经存在于Realm中(是托管对象)
确保你传入的account是通过Realm查询得到的托管对象,比如:
// 先查询得到托管的Account对象 Account managedAccount = realm.where(Account.class).equalTo("xxx", 你的查询条件值).findFirst(); if(managedAccount != null) { changeAccountAccessToken(managedAccount, srcAccessToken); }
同时,修改你的事务方法,确保操作的是托管对象:
public void changeAccountAccessToken(final Account account, final AccessToken srcAccessToken) { realm.executeTransaction(new Realm.Transaction() { @Override public void execute(Realm realm) { AccessToken accessToken = realm.createObject(AccessToken.class); accessToken.setAccessToken(srcAccessToken.getAccessToken()); accessToken.setExpirationDate(srcAccessToken.getExpirationDate()); // 对于托管的account,直接set即可完成关联持久化 account.setAccessToken(accessToken); } }); // 验证结果时,务必从Realm重新查询Account,不要用原来的实例 Account updatedAccount = realm.where(Account.class).equalTo("xxx", 你的查询条件值).findFirst(); // 此时updatedAccount.getAccessToken()应该不为null }
情况2:传入的Account是新创建的非托管对象
需要先将Account转为托管对象,再设置关联:
public void changeAccountAccessToken(final Account account, final AccessToken srcAccessToken) { realm.executeTransaction(new Realm.Transaction() { @Override public void execute(Realm realm) { // 将非托管的account转为Realm托管对象(不存在则插入,存在则更新) Account managedAccount = realm.copyToRealmOrUpdate(account); AccessToken accessToken = realm.createObject(AccessToken.class); accessToken.setAccessToken(srcAccessToken.getAccessToken()); accessToken.setExpirationDate(srcAccessToken.getExpirationDate()); managedAccount.setAccessToken(accessToken); } }); }
额外注意事项
- 不要用非托管对象验证结果:修改完成后,一定要从Realm中重新查询
Account对象来验证,因为之前的非托管实例不会自动同步Realm中的变更。 - 关联对象的加载规则:后续查询
Account的accessToken时,确保使用RealmQuery获取托管对象,Realm会自动加载关联的AccessToken数据。
内容的提问来源于stack exchange,提问作者Brian Hoang
相关产品推荐
相关产品推荐

