Sugar ORM just won't create tables
Asked Answered
E

3

18

I am working on a standalone library project that requires persisting a simple model. Here is what my SugarRecord looks like:

/**
 *  Keeping track of previously received messages by ID
 */

public class MessageRequestIdModel extends SugarRecord {

    protected String messageRequestId;

    public MessageRequestIdModel() {

    }

    public MessageRequestIdModel(String messageRequestId) {
        this.messageRequestId = messageRequestId;
    }

    public String getMessageRequestId() {
        return this.messageRequestId;
    }

    public static boolean exists(String id) {
        return MessageRequestIdModel.find(
                MessageRequestIdModel.class,
                "messageRequestId = ?",
                id
        ).size() != 0;
    }
}

In a repository class, I am attempting to persist it by calling this method:

@Override
public void save(MessageRequestId messageRequestId) {
    new MessageRequestIdModel(messageRequestId.getId()).save();
}

I now attempt to test this by using an android.test.InstrumentationTestCase where I pass a Context to Sugar like so:

SugarContext.init(getInstrumentation().getContext());

This results in this error when I run the test: (truncating to keep this question a succinct read)

android.database.sqlite.SQLiteException: no such table: MESSAGE_REQUEST_ID_MODEL (code 1): , while compiling: INSERT or REPLACE...

Troubleshooting I've already attempted:

  • Keeping a different Manifest for the test package to pass the .test package name to SugarORM. No change in behaviour
  • Adding a MessageRequestIdModel.findById(MessageRequestIdModel.class, (long) 1); like in the other SO posts. Changes error to itself (Showing full stack-trace here in case it helps):

    android.database.sqlite.SQLiteException: no such table: MESSAGE_REQUEST_ID_MODEL (code 1): , while compiling: SELECT * FROM MESSAGE_REQUEST_ID_MODEL WHERE id=? LIMIT 1
    
    at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
    at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:889)
    at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:500)
    at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
    at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
    at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
    at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:44)
    at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1316)
    at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1163)
    at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1034)
    at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1240)
    at com.orm.SugarRecord.find(SugarRecord.java:192)
    at com.orm.SugarRecord.findById(SugarRecord.java:102)
    at pm.tin.apprise.entities.message_request_ids.MessageRequestIdModelRepository.save(MessageRequestIdModelRepository.java:19)
    
  • I've tried removing all Sugar ORM config from the Manifest like suggested by many - this changes nothing

  • I've tried creating a Sample App module and tried running it as a test-case for that app, in case Standalone apps didn't get the right resources on the emulator/device (I've tested on both)

  • I've tried incrementing the VERSION number for the database

  • I've tried switching to an ActivityTestCase and using getActivity().getApplicationContext(). This essentially fails with an error that suggests that this Context is incomplete to be able to setup SQLite

As you can see, I have pushed hard at this boulder all night long, but at this point it is seeming Sisyphean and I have absolutely no lead for my next debug attempt other than to use a different ORM than Sugar (which doesn't really seem to be the problem). There is nothing more emasculating that not being able to run SQLite in a Test Case and I cry to the Holy Programmer Consciousness in you for help :-'(

Extirpate answered 3/3, 2016 at 7:28 Comment(4)
What version of Android Studio were you using? It may be related to the following issueJoint
@EdGeorge seems like it very much yes!Extirpate
Then I will add it as an answer :)Joint
@EdGeorge I am however on Gradle 1.5.0 :( It certainly might help somebody though yes - will follow this issue and if this fixes it switch as accepted answer!Extirpate
E
8

This should conclusively solve this problem for all the folks out there struggling to get Sugar ORM to work out of the box - use the SQL versioning system to manually fire creation SQL.

In the above use-case, here is how you do it:

1.) Change Sugar ORM config's DB version to a new number (say N) such that it is greater than the current version OR change database name

2.) Create a file ModuleName/src/main/assets/sugar_upgrades/<N>.sql with your SQL; showing mine, in case it helps:

DROP TABLE MESSAGE_REQUEST_ID_MODEL;

CREATE TABLE MESSAGE_REQUEST_ID_MODEL(ID INTEGER PRIMARY KEY AUTOINCREMENT, MESSAGE_REQUEST_ID CHAR(128));

This will force Sugar to fire your SQL to create the table for you (albeit manually).

Additional Notes

  • This section of the Sugar ORM manual is the inspiration behind this (albeit hacky) fix: http://satyan.github.io/sugar/migration.html
  • I have commented out the package name from Sugar config
  • Sugar works with an Instrumentation Application Context. In a base class of InstrumentationTestCase, simply do SugarContext.init(getInstrumentation().getTargetContext()) as shown in the original question
Extirpate answered 3/3, 2016 at 11:1 Comment(1)
You helped me man, this was the solution to my problem, Thank you :)Brandi
J
23

This issue has been observed in Android Studio 2.x.x-beta versions (most notably 2.0.0-beta6) and has its root cause in the 'Instant Run' feature.

I imagine this may be fixed shortly, but for this to work in the meantime, you should disable the feature in the following menu

File | Settings | Build, Execution, Deployment | Instant Run

Cleaning and then building the application should resolve these issues.

You can see the related Sugar bug report here.

Joint answered 11/3, 2016 at 14:30 Comment(3)
This is now fixed and in the master branch. See github.com/satyan/sugar/pull/564 it's not yet in an official release, but compile 'com.github.satyan:sugar:b16e65326a' has the fix (this uses jitpack)Susceptible
Got AS 2.3.1 and using the latest sugar .. still the same error :(Eous
I have instant run disabled and I'm getting the same error :(Factotum
E
8

This should conclusively solve this problem for all the folks out there struggling to get Sugar ORM to work out of the box - use the SQL versioning system to manually fire creation SQL.

In the above use-case, here is how you do it:

1.) Change Sugar ORM config's DB version to a new number (say N) such that it is greater than the current version OR change database name

2.) Create a file ModuleName/src/main/assets/sugar_upgrades/<N>.sql with your SQL; showing mine, in case it helps:

DROP TABLE MESSAGE_REQUEST_ID_MODEL;

CREATE TABLE MESSAGE_REQUEST_ID_MODEL(ID INTEGER PRIMARY KEY AUTOINCREMENT, MESSAGE_REQUEST_ID CHAR(128));

This will force Sugar to fire your SQL to create the table for you (albeit manually).

Additional Notes

  • This section of the Sugar ORM manual is the inspiration behind this (albeit hacky) fix: http://satyan.github.io/sugar/migration.html
  • I have commented out the package name from Sugar config
  • Sugar works with an Instrumentation Application Context. In a base class of InstrumentationTestCase, simply do SugarContext.init(getInstrumentation().getTargetContext()) as shown in the original question
Extirpate answered 3/3, 2016 at 11:1 Comment(1)
You helped me man, this was the solution to my problem, Thank you :)Brandi
M
1

your problem may be creation of class...

public class MessageRequestIdModel extends SugarRecord<MessageRequestIdModel> {

    protected String messageRequestId;

    public MessageRequestIdModel() {

    }

    public MessageRequestIdModel(String messageRequestId) {
        this.messageRequestId = messageRequestId;
    }

    public String getMessageRequestId() {
        return this.messageRequestId;
    }

    public static boolean exists(String id) {
        return MessageRequestIdModel.find(
                MessageRequestIdModel.class,
                "messageRequestId = ?",
                id
        ).size() != 0;
    }
}

please recheck with my code.

Munn answered 3/3, 2016 at 7:38 Comment(2)
Your syntax is for Sugar ORM 1.3, whereas I am on Sugar ORM 1.4. In 1.4, SugarRecord has no Generic Type Parameter, which means this won't even compile for me.Extirpate
OK. thanks for suggest me. you can increase version of Suger ORM by manifest and run once again.Munn

© 2022 - 2024 — McMap. All rights reserved.