【问题标题】:Setting unique indices in @FTS4 Room database causes build error在@FTS4 Room 数据库中设置唯一索引会导致构建错误
【发布时间】:2023-03-14 03:46:01
【问题描述】:

我试图通过定义索引来使我的 Room 数据库的一列唯一。但是,这导致我的编译器失败,因为它大大增加了所需的对象堆。

如果我使用@Entity(tableName = "seeds", indices = {@Index(value = {"name"}, unique = true)}) @Fts4

运行“gradlew build --stacktrace”时出现编译器错误:

Error occurred during initialization of VM
Could not reserve enough space for 3145728KB object heap

如果我只使用@Entity(tableName = "seeds") @Fts4,应用程序会正确编译。

我在gradle.properties中尝试了不同的设置...

org.gradle.jvmargs=-Xmx3g 是我能给它的最大价值。在4g 它抱怨该值超过了允许的最大值。因此,所有其他关于此的 SO 线程都没有帮助,因为我已经达到了最大值。我通常在2g 有它。所以这个“小”的变化似乎使所需的对象堆增加了一倍。

有人知道处理唯一索引的更好方法吗?

有谁知道如何解决这个级别的对象堆问题?

【问题讨论】:

  • “我明白了”——你从哪里得到这个消息?这是您在 Logcat 中看到的运行时错误吗?这是您在 Gradle 输出中看到的构建时错误吗?是别的吗?
  • 嘿@Co​​mmonsWare,感谢您的澄清:正如所说,它会导致编译器失败。所以这是我在 gradle 输出中看到的构建时错误。由于我在 android studio 中看不到编译器输出,因此我在终端中运行了“gradlew build --stacktrace”以获取此错误消息。我相应地更新了问题。
  • 唯一索引本身不会导致构建失败。我的书样回购中有this class,它构建和运行良好。因此,除了indices 属性之外,还有一些问题在这里出错。您可以尝试整理一个废弃项目,复制到您的@Entity,然后查看问题是否再次出现。如果是,请针对 Room 提交错误报告,并提供该示例项目作为演示。
  • 相反,如果废品项目构建并运行良好,那么当与 indices 结合使用时,您的主项目中还有其他东西会触发此问题。
  • :/好的@CommonsWare 我稍后会尝试做一个废品项目。但是您确认我设置唯一索引的方式基本正确?

标签: android jvm android-room fts4


【解决方案1】:

正如@CommonsWare 所说,@FTS4 表似乎不支持索引。

https://developer.android.com/training/data-storage/room/defining-data 网站上,他们提到:

如果您的应用必须支持不允许使用 FTS3 或 FTS4 表支持的实体的 SDK 版本,您仍然可以索引数据库中的某些列以加快查询速度。

现在让我假设,它们不支持 FTS3/4 上的索引..

我现在通过一种解决方法解决了唯一性问题,即在插入新对象之前检查列中是否存在匹配项:

/**
 * Add a SeedEntity object to the database,
 * if there is no entity in the database with the same name (non-case-sensitive)
 *
 * @param seedEntity Object that is supposed to be added to the database
 * @return  whether the Object has been added or not
 */
public boolean addSeed(SeedEntity seedEntity)
{
    for (SeedEntity entity : mObservableSeeds.getValue())
        if (entity.getName().toLowerCase().equals(seedEntity.getName().toLowerCase()))
            return false;

    mExecutors.diskIO().execute(() ->
            mDatabase.runInTransaction(() ->
                    mDatabase.seedDao().insert(seedEntity)
            )
    );
    return true;
}

不完全是我想要的,但现在解决了目的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-27
    • 1970-01-01
    • 1970-01-01
    • 2016-07-05
    • 2015-12-16
    • 1970-01-01
    • 2017-01-31
    相关资源
    最近更新 更多