chennaione / sugar

Insanely easy way to work with Android Database.
http://satyan.github.com/sugar/
MIT License
2.62k stars 583 forks source link

No such table #613

Open hubix786 opened 8 years ago

hubix786 commented 8 years ago

Hello, i have big problem with Sugar ORM implementation in my project. After hours of searching for working solution, i created new clean project to be sure, that none of another modules don't break sugar implementation. On new project with only implemented sugar i have still the same error "no such table". I tried lot of times changing VERSION metadata, extending app class with SugarApp, deleting whole app data, reinstalling app. Instant run is disabled. Problem occurs on Android Studio 1.5 with Gradle Plugin <2 and Android Studio 2.1.1 with Gradle plugin 2.1.0. Here is code of this test project, that generates this error too:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button test = (Button) findViewById(R.id.test);
        test.setOnClickListener(listener);
    }

    View.OnClickListener listener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            try {
                SugarContext.init(getApplicationContext());
                List<Test> testList = new ArrayList<>();
                for (int i = 0; i < 1000; i++) {
                    testList.add(new Test("Name "+i, "Content "+i));
                }
                Test.saveInTx(testList);
                testList = Test.listAll(Test.class);
                Test.deleteInTx(testList);
            } catch (Exception e) {
                e.printStackTrace();
                new AlertDialog.Builder(MainActivity.this).setMessage(e.getMessage()).create().show();
            }
        }
    };

    class Test extends SugarRecord {

        public String name;
        public String content;

        public Test() {
        }

        public Test(String name, String content) {
            this.name = name;
            this.content = content;
        }
    }
}
<application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>

        <meta-data android:name="DATABASE" android:value="sugarorm.db" />
        <meta-data android:name="VERSION" android:value="2" />
        <meta-data android:name="QUERY_LOG" android:value="true" />

    </application>

For request i can send zipped project. Thanks in advance

eric-tong commented 8 years ago

The new "Instant Run" feature has changed the ways some files are compiled, causing the error. See MR #564 for a temporary solution.

hubix786 commented 8 years ago

Unlucky no difference, I'm still getting No such table error

eric-tong commented 8 years ago

I use Android Studio 2.0 with Gradle 2.1.0 and it works with Instant Run. It may help if you use Studio 2.0 instead of 2.1

hubix786 commented 8 years ago

I'm afraid, that Android Studio 2.0 is no longer available to download. But I don't think that IDE version is cause of problem, because i developed my app on 1.5 version and on this version i had same error. Updating to newest version was attempt to find a solution. I'll try to run project on another computer with fresh install of IDE.

larrytech7 commented 8 years ago

Unless am unaware of recent version changes to sugar's configuration, you don't put SugarContext.init(getApplicationContext()); in your activity file. Initialize it in your Application class. also you are missing the DOMAIN_PACKAGE_NAME meta data in your manifest. Though not obligatory just add it and see whether it works for you.

larrytech7 commented 8 years ago

you may have to remove any data then uninstall and install the app again to try.

hubix786 commented 8 years ago

@larrytech7 I tried your advice, but it didn't work. Especially everytime I changed something in code I runned on new AVD. Here's updated code:

Entity class Test moved to subpackage entity

public class App extends SugarApp {
}
<application
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme"
        android:name=".App">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>

        <meta-data android:name="DATABASE" android:value="sugarorm.db" />
        <meta-data android:name="VERSION" android:value="2" />
        <meta-data android:name="QUERY_LOG" android:value="true" />
        <meta-data android:name="DOMAIN_PACKAGE_NAME" android:value="pl.dmcs.hubix786.testsugarorm.entity" />

    </application>
cutiko commented 8 years ago

Im having the same problem, but only happens with os 5.0 (API level 21) and above. Using Android Studio 2.1.1 and try to downgrade my graddle from 2.1 to 2.0 but still the same problem.

So I was very surprise about this cause this is working in another project no problems at all. The only difference was then the target sdk (maximun)

Momentaneously fix it by lowering the targetSdkVersion to 21 instead of 23

So probably the problem has something to do with the instant run.

I wish with all my heart you can fix this, I have compare with others ORM and sugar is my choice above all, Im very sorry for not being good enough to do a pull request, please fix it.

hubix786 commented 8 years ago

@larrytech7 I finally found solution with your big help. In project MUST be declared class extended by SugarApp (in fact it's application class) like this (overridden functions not required, but I want have some code inside class):

public class App extends SugarApp {
    @Override
    public void onCreate() {
        super.onCreate();
        SugarContext.init(this);
    }

    @Override
    public void onTerminate() {
        SugarContext.terminate();
        super.onTerminate();
    }
}

This application class must be specified in AndroidManifest.xml as master Application class like this:

<application
        ...
        android:name=".App">
        ...
</application>

And it works awesome! I don't know why i thought, that SugarContext.init(application) will be work anywhere and allows me to initialize where I want too.

@cutiko with this implementation I successfully run with targetSdkVersion 23. I use 1.5 version library.

Thank you everyone for your help and dedicated time.

cutiko commented 8 years ago

UPDATE [I was fooled by the Android Monitor, despite using the clear all several times, had to double check the hour to be sure]

@hubix786 thanks for letting me know, I can confirm this is a solution

I did several testings in a device running on API level 21 (originally found the problem there) and finally confirm the solution in a lower API level device. Im going to summarize my findings:

  1. Whatever class is extended to SugarApp must include the onCreate and onTerminate method, calling explicitly the super and SugarContext, just like is done in the previous example. So regards to "overridden functions not required", it is required, if omitted wont work.
  2. This doesnt work with graddle 2.1
  3. This does work with graddle 2.0 and 1.5 (as pointed before).
  4. This does work with targetSdk 23 (as pointed before)

The best scenario where graddle 2.1 can be use is not working, but for me using 2.0 it is good enough considering the targetSdk can be increased to 23.

Personally I would support if the Sugar team choose to include in the setup ,the creation of an Application type class. An Application type class could have other benefits, by example, help in other architectural problems such as having some objects availables for other classes, knowing the state of the app, or initializing a crash tracker.

JonatanSalas commented 8 years ago

The hotfix for this trouble is around the feature of Android Studio InstantRun. If you disable it, and run the avd you will see your app running with no trouble.

This bug has been solved with a PR, but it's not included in the latest version of sugarOrm.

lmvinicius commented 8 years ago

I have the same problem here, I have empty constructors in all my model classes, all the configs in the manifest, instant run disabled, created a class extending SugarApp, calling SugarContext.init and terminate. Tried with targetsdk 21 and 23, gradle 1.5 and 2.0, nothing works. Using Sugar 1.5. I always get an error saying that the table doesn't exist. Any other solution?

eric-tong commented 8 years ago

If nothing else works, you could create the tables manually.

SugarRecord.executeQuery("CREATE TABLE IF NOT EXISTS YOUR_CLASS_NAME (ID INTEGER PRIMARY KEY AUTOINCREMENT, YOUR_COLUMN_NAME TEXT, ANOTHER_COLUMN_NAME INTEGER)");

ghost commented 8 years ago

@lmvinicius did you find any solution ? The same problem!

amuttsch commented 8 years ago

I have debugged a bit and found the problem:

getAllClasses() in the MultiDexHelper doesn't return the application classes, only the ones from android. I guess some dex files are missing here that are not read and that contain the actual application classes.

I hope this helps to further investigate into this problem and finding a solution.

lmvinicius commented 8 years ago

@vleonovs I created the tables manually like @eric-tong said.

JonatanSalas commented 8 years ago

@vleonovs @lmvinicius @amuttsch @eric-tong The problem was around instantRun, when you run for first time the application you have to disable it, because the instantRun feature generates some .dex files that are not checked by sugarOrm v1.5.0. There is PR that has been merged and solve this trouble #564 but it's on the master branch, so this code has not been released yet.

RossinesP commented 8 years ago

Had the same issue, which I solved by reverting one line. See https://github.com/satyan/sugar/issues/519#issuecomment-242010880

EDIT : It works well with Gradle 2.14 and Gradle plugin 2.1.3

larrytech7 commented 8 years ago

Which line exactly @pierreRossines ?

2016-08-24 10:52 GMT+01:00 Pierre Rossinès notifications@github.com:

Had the same issue, which I solved by reverting one line. See #519 (comment) https://github.com/satyan/sugar/issues/519#issuecomment-242010880

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/satyan/sugar/issues/613#issuecomment-242012550, or mute the thread https://github.com/notifications/unsubscribe-auth/AGMQfa3LdSAzq6FDVs6dSKYH7_C_K7M2ks5qjBRSgaJpZM4Iocm5 .

Akah Larry N.H

Android Platform Engineer Founder IceTeck www.iceteck.com

Developing technologies for emergence and sustainable development.

RossinesP commented 8 years ago

In the ReflectionUtil.java file, replace the third line of the getDomainClass method with this one : discoveredClass = Class.forName(className, true, ContextUtil.getContext().getClass().getClassLoader());

EDIT : note that I still have Instant Run disabled

dirkvranckaert commented 8 years ago

So is there any way to enable instant run on the latest version of studio with gradle 2.14 and sugar ORM working?

vunguyen-it commented 8 years ago

I have the same issue, the weird thing is my error in logcat was shown like below while there is no A, B, C, D tables in my code (exactly my table class name is "BlockTable"):

"no such table: A Error in saving in transaction no such table: A (code 1): , while compiling: INSERT OR REPLACE INTO A(D,A,B,C) VALUES (?,?,?,?)"

Another weird thing that everything working good while running debug, but when i run in release mode then the app crash by the error above.

DroidPulkit commented 7 years ago

Dude this issue is still now? It's really disappointing the error persists

jack2799 commented 6 years ago

I am still getting this "Error in saving in transaction no such table: LINKED_HASH_MAP (code 1): " running gradle 3.0.1, disabled instant run, android studio 3.x, uninstalled app then ran again, changed version code, made App extends SugarApp class, targetversion 27. Nothing works.

mehrdadmmb2 commented 6 years ago

Hi i fixed this issues by change database name

InsanityOnABun commented 6 years ago

I get the same issue, but only when my build variant is set to debug. I've tried removing / adding metadata and disabling Instant Run. I haven't extended SugarApp yet, as the base class looks to be basically identical to hubix786's extension. For now, just doing everything as release builds is working.