问题描述
我试图通过定义索引使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
拥有它。因此,这种“小的”更改似乎使所需的对象堆增加了一倍。
有人知道更好的方式来处理唯一索引吗?
有人知道如何在此级别解决对象堆问题吗?
解决方法
如@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;
}
并非我要找的东西,但现在可以解决目的。