1

I tried to make a column of my Room database unique by defining indices. However, this caused my compiler to fail, as it drastically increases the required object heap.

If I use @Entity(tableName = "seeds", indices = {@Index(value = {"name"}, unique = true)}) @Fts4

I get a compiler error when running "gradlew build --stacktrace":

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

If I just use @Entity(tableName = "seeds") @Fts4, the app properly compiles.

I tried different settings in my gradle.properties...

org.gradle.jvmargs=-Xmx3g was the largest value I could give it. At 4g it complains that the value exceeds the allowed maximum. So all other SO threads regarding this are not helpfull as I already went to the maximum. I usually have it at 2g. So this "small" change seems to double the required object heap.

Does anyone know a better way to handle unique indices?

Does anyone know how to solve the object heap issue at this level?

Tobi
  • 858
  • 7
  • 15
  • "I get" -- where specifically do you get this message? Is this a runtime error that you are seeing in Logcat? Is this a build-time error that you are seeing in Gradle output? Is it something else? – CommonsWare Oct 23 '20 at 19:58
  • Hey @CommonsWare , thanks for the clarification: as said it causes the compiler to fail. So it's a build-time error that I see in the gradle output. Since I don't see compiler output in android studio, I ran "gradlew build --stacktrace" in a terminal to get to this error message. I updated the question accordingly. – Tobi Oct 24 '20 at 11:18
  • Unique indices on their own do not cause the build to fail. I have [this class](https://gitlab.com/commonsguy/cw-room/-/blob/v0.3/MiscSamples/src/main/java/com/commonsware/room/misc/UniqueIndexEntity.kt) in my repo of book samples, and it builds and runs fine. So, there is something beyond merely the `indices` property that is at fault here. You might try putting together a scrap project, copying in your `@Entity`, and see if the problem recurs there. If it does, file a bug report against Room, supplying that sample project as the demonstration. – CommonsWare Oct 24 '20 at 11:35
  • Conversely, if the scrap project builds and runs fine, then there is something else in your main project that is triggering this problem, when used in conjunction with `indices`. – CommonsWare Oct 24 '20 at 11:36
  • :/ alright @CommonsWare I'll give it a try to make a scrap project later. But you confirm that the way I set the unique indice is basically correct? – Tobi Oct 24 '20 at 11:52
  • @CommonsWare might my `@Fts4` flag cause some troubles? Seems you do not have a Fts4 format – Tobi Oct 24 '20 at 11:54
  • The one line of source in your question seems OK. And even if there is something strange about the class and `name`, Room's tools should detect that and gracefully fail the build, not attempt to allocate 3GB of heap space. "might my @Fts4 flag cause some troubles?" -- quite possibly. I'm not certain if Room (or SQLite for that matter) supports indices on an FTS4 shadow table. – CommonsWare Oct 24 '20 at 11:57
  • BTW and FWIW, [this class](https://gitlab.com/commonsguy/cw-room/-/blob/v0.3/FTS/src/main/java/com/commonsware/room/fts/ParagraphEntity.kt) is a normal entity, [this class](https://gitlab.com/commonsguy/cw-room/-/blob/v0.3/FTS/src/main/java/com/commonsware/room/fts/ParagraphFtsEntity.kt) is an `@Fts4` shadow of the first class, and [this DAO function](https://gitlab.com/commonsguy/cw-room/-/blob/v0.3/FTS/src/main/java/com/commonsware/room/fts/BookStore.kt#L31-34) is how I get the real data using the FTS4 index, via a `JOIN`. – CommonsWare Oct 24 '20 at 12:18

1 Answers1

1

As @CommonsWare stated, it seems like @FTS4 tables do not support indices.

On the website https://developer.android.com/training/data-storage/room/defining-data they mention:

If your app must support SDK versions that don't allow for using FTS3- or FTS4-table-backed entities, you can still index certain columns in the database to speed up your queries.

What let's me assume now, that they do not support indices on FTS3/4..

I solved uniqueness now with a workaround, that checks whether there is a match in the column before inserting a new object:

/**
 * 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;
}

Not exactly what I was looking for, but solves the purpose now.

Tobi
  • 858
  • 7
  • 15