【问题标题】:A RealmObject with no @PrimaryKey cannot be updated没有 @PrimaryKey 的 RealmObject 无法更新
【发布时间】:2016-02-21 16:34:30
【问题描述】:

我目前正在重构一些旧应用程序,并且正在尝试从 SQLite 迁移到 Realm。我以前用过Realm,从来没有遇到过这样的问题。当我第一次启动我的应用程序时(安装后),我得到了这个异常:

E/AndroidRuntime: FATAL EXCEPTION:
Process: xx.xxx.xxx.beta.realm, PID: 25947
java.lang.IllegalArgumentException: A RealmObject with no @PrimaryKey cannot be updated: class xx.xxx.xxx.realm.Vod
   at io.realm.Realm.checkHasPrimaryKey(Realm.java:1184)
   at io.realm.Realm.copyToRealmOrUpdate(Realm.java:713)
   at xx.xxx.xxx.services.VodService$4.run(VodService.java:232)
   at java.lang.Thread.run(Thread.java:818)

我的 Vod 类看起来像这样,并且对象已正确创建,即具有 PrimaryKey 和所有其他字段的值:

public class Vod extends RealmObject {

    @PrimaryKey
    private String uuid;

    private String name;
    private Integer lengthMin;
    private Boolean hasTrailer;
    private String description;
    private String originalName;

    //etc...

    //getters & setters

这会使应用程序崩溃。但是在第一次(以及每次下一次)之后,一切正常 - 使用相同的代码和相同的数据。但是当我再次卸载并重新安装应用程序时,我也会再次遇到此异常。 有问题的代码部分在后台线程上运行。如果我将它移到 UI 线程,即使是第一次也一切正常。但我想在后台线程而不是 UI 上解析网络响应。此外,它不是特定于 Vod 类的,如果我跳过 Vod 的数据并从 User 类开始,那么我会得到 User 类的“no @PrimaryKey”异常。

有时它也会抛出这个异常:

D/REALM: jni: ThrowingException 5, , .
D/REALM: Exception has been throw: File not found: .
E/AndroidRuntime: FATAL EXCEPTION:
   Process: xx.xxx.xxx.beta.realm, PID: 28555
   io.realm.exceptions.RealmIOException: File not found: .
       at io.realm.internal.SharedGroup.createNativeWithImplicitTransactions(Native Method)
       at io.realm.internal.SharedGroup.<init>(SharedGroup.java:67)
       at io.realm.internal.SharedGroupManager.<init>(SharedGroupManager.java:47)
       at io.realm.BaseRealm.<init>(BaseRealm.java:76)
       at io.realm.Realm.<init>(Realm.java:126)
       at io.realm.Realm.createAndValidate(Realm.java:246)
       at io.realm.Realm.createInstance(Realm.java:231)
       at io.realm.RealmCache.createRealmOrGetFromCache(RealmCache.java:114)
       at io.realm.Realm.getDefaultInstance(Realm.java:181)
       at xx.xxx.xx.services.RecordingService$9.run(RecordingService.java:317)
    at java.lang.Thread.run(Thread.java:818) 

这让我想到,Realm 文件的初始化会有一些问题吗?我是这样创建的:

public class MainApplication extends Application {

  private static Context mContext;

  @Override
  public void onCreate() {
    super.onCreate(); 

    mContext = getApplicationContext();

    mRealmConfig = new RealmConfiguration.Builder(mContext).build();
    Realm.setDefaultConfiguration(mRealmConfig);
  }
}

然后使用它在线程中获取实例:

Realm localRealm = Realm.getDefaultInstance();

我做错了吗?以前有人遇到过这种问题吗?我试图在网上搜索答案,但没有发现任何有用的东西。感谢您的帮助。

(我正在使用 io.realm:realm-android:0.87.4)

编辑:我已经确认(通过 ADB),我的应用程序包的内部存储文件夹在卸载后被删除。在检查时,我发现路径 /data/data//files 中的文件夹在第一次应用程序运行期间为空。这是正确的行为吗?此外,我无法通过 Stetho 看到 Realm 内部的任何内容。

步骤: 1.我卸载应用程序

  1. ADB 说 cd: /data/data/xx.xxx.xxx.beta.realm: 没有这样的文件或目录

  2. 我再次安装并运行应用程序

  3. ADB 运行为 xx.xxx.xxx.beta.realm -> cd 文件 -> ls -> 空

  4. 通过 Stetho 检查,未显示数据

  5. 等待一分钟左右(让 Realm 有时间创建任何需求)

  6. 启动网络请求和应用程序崩溃(“无 @PrimaryKey”异常),首先要在 UI 线程之外解析数据(在 UI 上解析工作正常)

  7. ADB -> 文件夹 -> ls -> 我可以看到一切,default.realm, default.realm.lock, default.realm.log, default.realm.log_a, default.realm.log_b

  8. 再次启动应用程序,一切正常,我什至可以通过以下方式查看领域数据 听诊器。

我真的希望我犯了一些愚蠢的错误,最后一切都会好起来的。还有一件事,在应用启动时,我多次看到此日志:

Rejecting re-init on previously-failed class java.lang.Class<io.realm.rx.RealmObservableFactory$4>

我已阅读此内容:https://github.com/realm/realm-java/issues/1990 我不认为这与我的问题有关,但只是为了确定。

【问题讨论】:

  • I experienced strange behaviour 在应用卸载时未删除 Realm 商店 - 您可能会看到类似的情况?
  • 您的应用中有迁移吗?服务是否在其他进程中运行?
  • 我正在使用它来处理迁移:public static Realm buildDatabase() { RealmConfiguration config = new RealmConfiguration.Builder(MainApplication.getContext()).build(); try { return Realm.getInstance(config); } catch (RealmMigrationNeededException e){ try { Realm.deleteRealm(config); //Realm file has been deleted. return Realm.getInstance(config); } catch (Exception ex){ throw ex; //No Realm file to remove. } } } 但它从不抛出 RealmMigrationNeededException
  • 当您删除重命名时,异常可能是由竞争条件引起的(但我很困惑,您说迁移永远不会触发。)。 realm.io/docs/java/latest/api/io/realm/…开发时尝试用这个做删除。
  • 好吧,我并没有真正删除应用程序中的任何内容。 Resp。,我通过手机设置卸载应用程序,这也应该删除领域文件(或不?)。因此,当我安装新实例时,我的状态是干净的,并且没有要删除的应用程序领域文件,因此无需抛出迁移异常。但我可以添加“deleteRealmIfMigrationNeeded()”并再次测试。

标签: android realm


【解决方案1】:

您的导入可能搞砸了。请务必导入io.realm.annotations.PrimaryKey,而不是androidx.room.PrimaryKey,这可能是一个常见问题。

【讨论】:

  • 就是这样,要多注意我告诉我的 IDE 导入的内容。谢谢!
猜你喜欢
  • 2019-05-02
  • 1970-01-01
  • 2018-09-13
  • 2017-02-03
  • 1970-01-01
  • 2015-06-13
  • 1970-01-01
  • 1970-01-01
  • 2014-12-28
相关资源
最近更新 更多