Search code examples
androidandroid-sqliteactiveandroid

ActiveAndroid Error - No such table while compiling - Only when selecting data


I have two annotated ActiveAndroid model classes, Term and Course (1 to many relationship).

I am able to create Term and Course objects and call .save() on them without any errors.

However, when I try to query the objects outside of accessing their members directly, I receive the error:

no such table: Terms (code 1 SQLITE_ERROR):, while compiling: SELECT * FROM Terms ORDER BY RANDOM()

Or a similar if I try to query courses.

I have not changed my schema as far as I am aware.

Things I have tried: 1. Uninstalling and reinstalling app in emulator. 2. Changing AA_DB_VERSION in Android manifest.

Manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.gilbertdev.wgu.c196.abm1">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <meta-data
            android:name="AA_MODELS"
            android:value="com.gilbertdev.wgu.c196.abm1.Term, com.gilbertdev.wgu.c196.abm1.Course" />
        <meta-data android:name="AA_DB_VERSION" android:value="10" />
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>

Dependencies:

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    implementation files('libs/activeandroid-3.0.jar')
}    

Term.java

package com.gilbertdev.wgu.c196.abm1;

import com.activeandroid.Model;
import com.activeandroid.annotation.Column;
import com.activeandroid.annotation.Table;

import java.util.Date;

@Table(name = "Terms")
public class Term extends Model {

    @Column(name = "title")
    public String title;

    @Column(name = "startdate")
    public Date startdate;

    @Column(name = "enddate")
    public Date enddate;

    //@Column(name = "course")
    //public Course course;

    public Term () {
        super();
    }
}

Course.java

package com.gilbertdev.wgu.c196.abm1;

import com.activeandroid.Model;
import com.activeandroid.annotation.Column;
import com.activeandroid.annotation.Table;

import java.util.Date;

@Table(name = "Courses")
public class Course extends Model {

    @Column(name = "title")
    public String title;

    @Column(name = "startdate")
    public Date startdate;

    @Column(name = "enddate")
    public Date enddate;

    @Column(name = "status")
    public String status;

    @Column(name = "term")
    public Term term;

    public Course() {
        super();
    }
}

MainActivity.java

package com.gilbertdev.wgu.c196.abm1;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

import com.activeandroid.ActiveAndroid;
import com.activeandroid.Model;
import com.activeandroid.query.Select;

import java.util.Date;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    TextView testView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActiveAndroid.initialize(this);
        setContentView(R.layout.activity_main);

        testView = (TextView) findViewById(R.id.testtext);

        testView.append("\nGilbert\n");

        Term firstterm = new Term();
        firstterm.title = "First term";
        firstterm.startdate = new Date(1991, 2, 20);
        firstterm.enddate = new Date(2100, 2, 20);
        firstterm.save();

        Course firstcourse = new Course();
        firstcourse.title = "First course";
        firstcourse.startdate = new Date(2018, 1, 13);
        firstcourse.enddate = new Date(2018, 1, 20);
        firstcourse.status = "In Progress";
        firstcourse.term = firstterm;
        firstcourse.save();

        testView.append(firstterm.title + "\n");
        testView.append(firstterm.startdate + "\n");
        testView.append(firstcourse.term.title + "\n");

        try {

            List<Course> courses = new Select()
                    .from(Course.class)
                    .where("Term = ?", firstterm.getId())
                    .orderBy("title ASC")
                    .execute();

            for (Course course : courses) {
                testView.append(course.status);
            }

//            Term test = new Select().from(Term.class).orderBy("RANDOM()").executeSingle();
//            testView.append(test.title);

        } catch (Exception e) {
            testView.append(e.getMessage());
        }
    }
}

Solution

  • I tried another ORM and had the same issue so I figured there was something weird going on that was not specific to ActiveAndroid. I used the Device File Explorer in Android Studio to copy the SQLite DB files created by both ORMs, opened them and saw no tables were ever created and no data was persisted after calling .save()

    How to fix:

    1. Disable Instant Run in Android Studio

    On Mac, navigate to Android Studio -> Preferences -> Build, Execution, Deployment -> Instant Run, and uncheck Enable Instant Run.

    1. Clear your existing DB files so your ORM can rebuild them

    You can do this in Android Studio by navigating to View -> Tool Windows -> Device File Explorer, then data/data/com.yoursite.yourapp/databases, and deleting any relevant .db files.