I am using DBflow in my application right now and I wanted to modify a table by inserting a new column called categoryId
. So I searched a little bit and I found out that I had to write a migration script to handle this modification in my table "Task". The problem is that I don't know what went wrong, but I got an error saying that there was no such column.
I uninstalled the app and install it back again and it worked just fine. The problem is that I have some other users getting the same error and I don't know what is causing it.
/**
* This is generated code. Please do not modify */
public final class Task_Table extends ModelAdapter<Task> {
/**
* Primary Key */
public static final Property<String> id = new Property<String>(Task.class, "id");
public static final Property<String> project_id = new Property<String>(Task.class, "project_id");
public static final Property<String> title = new Property<String>(Task.class, "title");
public static final Property<String> description = new Property<String>(Task.class, "description");
public static final Property<String> collection_id = new Property<String>(Task.class, "collection_id");
public static final Property<Integer> priority = new Property<Integer>(Task.class, "priority");
public static final TypeConvertedProperty<Long, Date> created_at = new TypeConvertedProperty<Long, Date>(Task.class, "created_at", true,
new TypeConvertedProperty.TypeConverterGetter() {
@Override
public TypeConverter getTypeConverter(Class<?> modelClass) {
Task_Table adapter = (Task_Table) FlowManager.getInstanceAdapter(modelClass);
return adapter.global_typeConverterDateConverter;
}
});
public static final Property<String> created_by = new Property<String>(Task.class, "created_by");
public static final TypeConvertedProperty<Long, Date> updated_at = new TypeConvertedProperty<Long, Date>(Task.class, "updated_at", true,
new TypeConvertedProperty.TypeConverterGetter() {
@Override
public TypeConverter getTypeConverter(Class<?> modelClass) {
Task_Table adapter = (Task_Table) FlowManager.getInstanceAdapter(modelClass);
return adapter.global_typeConverterDateConverter;
}
});
public static final TypeConvertedProperty<Long, Date> due_date = new TypeConvertedProperty<Long, Date>(Task.class, "due_date", true,
new TypeConvertedProperty.TypeConverterGetter() {
@Override
public TypeConverter getTypeConverter(Class<?> modelClass) {
Task_Table adapter = (Task_Table) FlowManager.getInstanceAdapter(modelClass);
return adapter.global_typeConverterDateConverter;
}
});
public static final TypeConvertedProperty<Long, Date> completed_at = new TypeConvertedProperty<Long, Date>(Task.class, "completed_at", true,
new TypeConvertedProperty.TypeConverterGetter() {
@Override
public TypeConverter getTypeConverter(Class<?> modelClass) {
Task_Table adapter = (Task_Table) FlowManager.getInstanceAdapter(modelClass);
return adapter.global_typeConverterDateConverter;
}
});
public static final Property<String> completed_by = new Property<String>(Task.class, "completed_by");
public static final Property<String> categoryId = new Property<String>(Task.class, "categoryId");
public static final Property<Integer> feed_count = new Property<Integer>(Task.class, "feed_count");
public static final Property<Integer> read_count = new Property<Integer>(Task.class, "read_count");
public static final IProperty[] ALL_COLUMN_PROPERTIES = new IProperty[]{id,project_id,title,description,collection_id,priority,created_at,created_by,updated_at,due_date,completed_at,completed_by,categoryId,feed_count,read_count};
private final DateConverter global_typeConverterDateConverter;
public Task_Table(DatabaseHolder holder, DatabaseDefinition databaseDefinition) {
super(databaseDefinition);
global_typeConverterDateConverter = (DateConverter) holder.getTypeConverterForClass(Date.class);
}
@Override
public final Class<Task> getModelClass() {
return Task.class;
}
@Override
public final String getTableName() {
return "`Task`";
}
@Override
public final Task newInstance() {
return new Task();
}
@Override
public final Property getProperty(String columnName) {
columnName = QueryBuilder.quoteIfNeeded(columnName);
switch ((columnName)) {
case "`id`": {
return id;
}
case "`project_id`": {
return project_id;
}
case "`title`": {
return title;
}
case "`description`": {
return description;
}
case "`collection_id`": {
return collection_id;
}
case "`priority`": {
return priority;
}
case "`created_at`": {
return created_at;
}
case "`created_by`": {
return created_by;
}
case "`updated_at`": {
return updated_at;
}
case "`due_date`": {
return due_date;
}
case "`completed_at`": {
return completed_at;
}
case "`completed_by`": {
return completed_by;
}
case "`categoryId`": {
return categoryId;
}
case "`feed_count`": {
return feed_count;
}
case "`read_count`": {
return read_count;
}
default: {
throw new IllegalArgumentException("Invalid column name passed. Ensure you are calling the correct table's column");
}
}
}
@Override
public final IProperty[] getAllColumnProperties() {
return ALL_COLUMN_PROPERTIES;
}
@Override
public final void bindToInsertValues(ContentValues values, Task model) {
values.put("`id`", model.getId() != null ? model.getId() : null);
values.put("`project_id`", model.getProjectId() != null ? model.getProjectId() : null);
values.put("`title`", model.getTitle() != null ? model.getTitle() : null);
values.put("`description`", model.getDescription() != null ? model.getDescription() : null);
values.put("`collection_id`", model.getCollectionId() != null ? model.getCollectionId() : null);
values.put("`priority`", model.getPriority());
Long refmCreatedAt = model.getCreatedAt() != null ? global_typeConverterDateConverter.getDBValue(model.getCreatedAt()) : null;
values.put("`created_at`", refmCreatedAt != null ? refmCreatedAt : null);
values.put("`created_by`", model.getCreatedById() != null ? model.getCreatedById() : null);
Long refmUpdatedAt = model.getUpdatedAt() != null ? global_typeConverterDateConverter.getDBValue(model.getUpdatedAt()) : null;
values.put("`updated_at`", refmUpdatedAt != null ? refmUpdatedAt : null);
Long refmDueDate = model.getDueDate() != null ? global_typeConverterDateConverter.getDBValue(model.getDueDate()) : null;
values.put("`due_date`", refmDueDate != null ? refmDueDate : null);
Long refmCompletedAt = model.getCompletedAt() != null ? global_typeConverterDateConverter.getDBValue(model.getCompletedAt()) : null;
values.put("`completed_at`", refmCompletedAt != null ? refmCompletedAt : null);
values.put("`completed_by`", model.getCompletedById() != null ? model.getCompletedById() : null);
values.put("`categoryId`", model.getCategoryId() != null ? model.getCategoryId() : null);
values.put("`feed_count`", model.getFeedCount());
values.put("`read_count`", model.getReadCount());
}
@Override
public final void bindToInsertStatement(DatabaseStatement statement, Task model, int start) {
statement.bindStringOrNull(1 + start, model.getId());
statement.bindStringOrNull(2 + start, model.getProjectId());
statement.bindStringOrNull(3 + start, model.getTitle());
statement.bindStringOrNull(4 + start, model.getDescription());
statement.bindStringOrNull(5 + start, model.getCollectionId());
statement.bindLong(6 + start, model.getPriority());
Long refmCreatedAt = model.getCreatedAt() != null ? global_typeConverterDateConverter.getDBValue(model.getCreatedAt()) : null;
statement.bindNumberOrNull(7 + start, refmCreatedAt);
statement.bindStringOrNull(8 + start, model.getCreatedById());
Long refmUpdatedAt = model.getUpdatedAt() != null ? global_typeConverterDateConverter.getDBValue(model.getUpdatedAt()) : null;
statement.bindNumberOrNull(9 + start, refmUpdatedAt);
Long refmDueDate = model.getDueDate() != null ? global_typeConverterDateConverter.getDBValue(model.getDueDate()) : null;
statement.bindNumberOrNull(10 + start, refmDueDate);
Long refmCompletedAt = model.getCompletedAt() != null ? global_typeConverterDateConverter.getDBValue(model.getCompletedAt()) : null;
statement.bindNumberOrNull(11 + start, refmCompletedAt);
statement.bindStringOrNull(12 + start, model.getCompletedById());
statement.bindStringOrNull(13 + start, model.getCategoryId());
statement.bindLong(14 + start, model.getFeedCount());
statement.bindLong(15 + start, model.getReadCount());
}
@Override
public final void bindToUpdateStatement(DatabaseStatement statement, Task model) {
statement.bindStringOrNull(1, model.getId());
statement.bindStringOrNull(2, model.getProjectId());
statement.bindStringOrNull(3, model.getTitle());
statement.bindStringOrNull(4, model.getDescription());
statement.bindStringOrNull(5, model.getCollectionId());
statement.bindLong(6, model.getPriority());
Long refmCreatedAt = model.getCreatedAt() != null ? global_typeConverterDateConverter.getDBValue(model.getCreatedAt()) : null;
statement.bindNumberOrNull(7, refmCreatedAt);
statement.bindStringOrNull(8, model.getCreatedById());
Long refmUpdatedAt = model.getUpdatedAt() != null ? global_typeConverterDateConverter.getDBValue(model.getUpdatedAt()) : null;
statement.bindNumberOrNull(9, refmUpdatedAt);
Long refmDueDate = model.getDueDate() != null ? global_typeConverterDateConverter.getDBValue(model.getDueDate()) : null;
statement.bindNumberOrNull(10, refmDueDate);
Long refmCompletedAt = model.getCompletedAt() != null ? global_typeConverterDateConverter.getDBValue(model.getCompletedAt()) : null;
statement.bindNumberOrNull(11, refmCompletedAt);
statement.bindStringOrNull(12, model.getCompletedById());
statement.bindStringOrNull(13, model.getCategoryId());
statement.bindLong(14, model.getFeedCount());
statement.bindLong(15, model.getReadCount());
statement.bindStringOrNull(16, model.getId());
}
@Override
public final void bindToDeleteStatement(DatabaseStatement statement, Task model) {
statement.bindStringOrNull(1, model.getId());
}
@Override
public final String getCompiledStatementQuery() {
return "INSERT INTO `Task`(`id`,`project_id`,`title`,`description`,`collection_id`,`priority`,`created_at`,`created_by`,`updated_at`,`due_date`,`completed_at`,`completed_by`,`categoryId`,`feed_count`,`read_count`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
}
@Override
public final String getUpdateStatementQuery() {
return "UPDATE `Task` SET `id`=?,`project_id`=?,`title`=?,`description`=?,`collection_id`=?,`priority`=?,`created_at`=?,`created_by`=?,`updated_at`=?,`due_date`=?,`completed_at`=?,`completed_by`=?,`categoryId`=?,`feed_count`=?,`read_count`=? WHERE `id`=?";
}
@Override
public final String getDeleteStatementQuery() {
return "DELETE FROM `Task` WHERE `id`=?";
}
@Override
public final String getCreationQuery() {
return "CREATE TABLE IF NOT EXISTS `Task`(`id` TEXT, `project_id` TEXT, `title` TEXT, `description` TEXT, `collection_id` TEXT, `priority` INTEGER, `created_at` TEXT, `created_by` TEXT, `updated_at` TEXT, `due_date` TEXT, `completed_at` TEXT, `completed_by` TEXT, `categoryId` TEXT, `feed_count` INTEGER, `read_count` INTEGER, PRIMARY KEY(`id`))";
}
@Override
public final void loadFromCursor(FlowCursor cursor, Task model) {
model.setId(cursor.getStringOrDefault("id"));
model.setProjectId(cursor.getStringOrDefault("project_id"));
model.setTitle(cursor.getStringOrDefault("title"));
model.setDescription(cursor.getStringOrDefault("description"));
model.setCollectionId(cursor.getStringOrDefault("collection_id"));
model.setPriority(cursor.getIntOrDefault("priority"));
int index_created_at = cursor.getColumnIndex("created_at");
if (index_created_at != -1 && !cursor.isNull(index_created_at)) {
model.setCreatedAt(global_typeConverterDateConverter.getModelValue(cursor.getLong(index_created_at)));
} else {
model.setCreatedAt(global_typeConverterDateConverter.getModelValue(null));
}
model.setCreatedById(cursor.getStringOrDefault("created_by"));
int index_updated_at = cursor.getColumnIndex("updated_at");
if (index_updated_at != -1 && !cursor.isNull(index_updated_at)) {
model.setUpdatedAt(global_typeConverterDateConverter.getModelValue(cursor.getLong(index_updated_at)));
} else {
model.setUpdatedAt(global_typeConverterDateConverter.getModelValue(null));
}
int index_due_date = cursor.getColumnIndex("due_date");
if (index_due_date != -1 && !cursor.isNull(index_due_date)) {
model.setDueDate(global_typeConverterDateConverter.getModelValue(cursor.getLong(index_due_date)));
} else {
model.setDueDate(global_typeConverterDateConverter.getModelValue(null));
}
int index_completed_at = cursor.getColumnIndex("completed_at");
if (index_completed_at != -1 && !cursor.isNull(index_completed_at)) {
model.setCompletedAt(global_typeConverterDateConverter.getModelValue(cursor.getLong(index_completed_at)));
} else {
model.setCompletedAt(global_typeConverterDateConverter.getModelValue(null));
}
model.setCompletedById(cursor.getStringOrDefault("completed_by"));
model.setCategoryId(cursor.getStringOrDefault("categoryId"));
model.setFeedCount(cursor.getIntOrDefault("feed_count"));
model.setReadCount(cursor.getIntOrDefault("read_count"));
model.loadPermissions();
model.loadChecklists();
model.loadMarkers();
model.loadAttachments();
}
@Override
public final boolean exists(Task model, DatabaseWrapper wrapper) {
return SQLite.selectCountOf()
.from(Task.class)
.where(getPrimaryConditionClause(model))
.hasData(wrapper);
}
@Override
public final OperatorGroup getPrimaryConditionClause(Task model) {
OperatorGroup clause = OperatorGroup.clause();
clause.and(id.eq(model.getId()));
return clause;
}
@Override
public final boolean save(Task model) {
boolean successful = super.save(model);
if (model.savePermissions() != null) {
ModelAdapter<Permission> adapter = FlowManager.getModelAdapter(Permission.class);
adapter.saveAll(model.savePermissions());
}
if (model.saveChecklists() != null) {
ModelAdapter<Checklist> adapter = FlowManager.getModelAdapter(Checklist.class);
adapter.saveAll(model.saveChecklists());
}
if (model.saveMarkers() != null) {
ModelAdapter<Marker> adapter = FlowManager.getModelAdapter(Marker.class);
adapter.saveAll(model.saveMarkers());
}
if (model.saveAttachments() != null) {
ModelAdapter<Attachment> adapter = FlowManager.getModelAdapter(Attachment.class);
adapter.saveAll(model.saveAttachments());
}
return successful;
}
@Override
public final long insert(Task model) {
long rowId = super.insert(model);
if (model.savePermissions() != null) {
ModelAdapter<Permission> adapter = FlowManager.getModelAdapter(Permission.class);
adapter.insertAll(model.savePermissions());
}
if (model.saveChecklists() != null) {
ModelAdapter<Checklist> adapter = FlowManager.getModelAdapter(Checklist.class);
adapter.insertAll(model.saveChecklists());
}
if (model.saveMarkers() != null) {
ModelAdapter<Marker> adapter = FlowManager.getModelAdapter(Marker.class);
adapter.insertAll(model.saveMarkers());
}
if (model.saveAttachments() != null) {
ModelAdapter<Attachment> adapter = FlowManager.getModelAdapter(Attachment.class);
adapter.insertAll(model.saveAttachments());
}
return rowId;
}
@Override
public final boolean update(Task model) {
boolean successful = super.update(model);
if (model.savePermissions() != null) {
ModelAdapter<Permission> adapter = FlowManager.getModelAdapter(Permission.class);
adapter.updateAll(model.savePermissions());
}
if (model.saveChecklists() != null) {
ModelAdapter<Checklist> adapter = FlowManager.getModelAdapter(Checklist.class);
adapter.updateAll(model.saveChecklists());
}
if (model.saveMarkers() != null) {
ModelAdapter<Marker> adapter = FlowManager.getModelAdapter(Marker.class);
adapter.updateAll(model.saveMarkers());
}
if (model.saveAttachments() != null) {
ModelAdapter<Attachment> adapter = FlowManager.getModelAdapter(Attachment.class);
adapter.updateAll(model.saveAttachments());
}
return successful;
}
@Override
public final boolean save(Task model, DatabaseWrapper wrapper) {
boolean successful = super.save(model, wrapper);
if (model.savePermissions() != null) {
ModelAdapter<Permission> adapter = FlowManager.getModelAdapter(Permission.class);
adapter.saveAll(model.savePermissions(), wrapper);
}
if (model.saveChecklists() != null) {
ModelAdapter<Checklist> adapter = FlowManager.getModelAdapter(Checklist.class);
adapter.saveAll(model.saveChecklists(), wrapper);
}
if (model.saveMarkers() != null) {
ModelAdapter<Marker> adapter = FlowManager.getModelAdapter(Marker.class);
adapter.saveAll(model.saveMarkers(), wrapper);
}
if (model.saveAttachments() != null) {
ModelAdapter<Attachment> adapter = FlowManager.getModelAdapter(Attachment.class);
adapter.saveAll(model.saveAttachments(), wrapper);
}
return successful;
}
@Override
public final long insert(Task model, DatabaseWrapper wrapper) {
long rowId = super.insert(model, wrapper);
if (model.savePermissions() != null) {
ModelAdapter<Permission> adapter = FlowManager.getModelAdapter(Permission.class);
adapter.insertAll(model.savePermissions(), wrapper);
}
if (model.saveChecklists() != null) {
ModelAdapter<Checklist> adapter = FlowManager.getModelAdapter(Checklist.class);
adapter.insertAll(model.saveChecklists(), wrapper);
}
if (model.saveMarkers() != null) {
ModelAdapter<Marker> adapter = FlowManager.getModelAdapter(Marker.class);
adapter.insertAll(model.saveMarkers(), wrapper);
}
if (model.saveAttachments() != null) {
ModelAdapter<Attachment> adapter = FlowManager.getModelAdapter(Attachment.class);
adapter.insertAll(model.saveAttachments(), wrapper);
}
return rowId;
}
@Override
public final boolean update(Task model, DatabaseWrapper wrapper) {
boolean successful = super.update(model, wrapper);
if (model.savePermissions() != null) {
ModelAdapter<Permission> adapter = FlowManager.getModelAdapter(Permission.class);
adapter.updateAll(model.savePermissions(), wrapper);
}
if (model.saveChecklists() != null) {
ModelAdapter<Checklist> adapter = FlowManager.getModelAdapter(Checklist.class);
adapter.updateAll(model.saveChecklists(), wrapper);
}
if (model.saveMarkers() != null) {
ModelAdapter<Marker> adapter = FlowManager.getModelAdapter(Marker.class);
adapter.updateAll(model.saveMarkers(), wrapper);
}
if (model.saveAttachments() != null) {
ModelAdapter<Attachment> adapter = FlowManager.getModelAdapter(Attachment.class);
adapter.updateAll(model.saveAttachments(), wrapper);
}
return successful;
}
}
I managed to insert other columns in other tables and I didn't get the same error. For an example, the migration script I ran in my DataBase to insert the column "categoryId" was similar to this one:
@Database(name = ConstructDB.NAME, version = ConstructDB.VERSION)
public class ConstructDB {
public static final String NAME = "construct_v3";
public static final int VERSION = 22;
@Migration(version = 21, database = ConstructDB.class)
public static class Migration21 extends AlterTableMigration<UserProject> {
public Migration21(Class<UserProject> table) {
super(table);
}
@Override
public void onPreMigrate() {
super.onPreMigrate();
addColumn(SQLiteType.TEXT, "load");
}
}
}
This is the LogCat I received through CrashLytics:
Fatal Exception: android.database.sqlite.SQLiteException: no such column: categoryId (code 1): , while compiling: SELECT `id`,`project_id`,`title`,`description`,`collection_id`,`priority`,`created_at`,`created_by`,`updated_at`,`due_date`,`completed_at`,`completed_by`,`categoryId`,`feed_count`,`R`.`read_count` FROM `Task` AS `T` LEFT OUTER JOIN `TaskRead` AS `R` ON `id`=`task_id` WHERE (`project_id`='5716f387d07c5a887cf97c4b' AND `completed_at` IS NULL ) ORDER BY `due_date` ASC, `priority` DESC, `created_at` ASC LIMIT 2147483647
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(SQLiteConnection.java)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:898)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:509)
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:1346)
at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1285)
at com.raizlabs.android.dbflow.structure.database.AndroidDatabase.rawQuery(AndroidDatabase.java:62)
at com.raizlabs.android.dbflow.sql.queriable.ModelLoader.load(ModelLoader.java:59)
at com.raizlabs.android.dbflow.sql.queriable.ListModelLoader.load(ListModelLoader.java:44)
at com.raizlabs.android.dbflow.sql.queriable.ListModelLoader.load(ListModelLoader.java:15)
at com.raizlabs.android.dbflow.sql.queriable.ModelLoader.load(ModelLoader.java:53)
at com.raizlabs.android.dbflow.sql.queriable.ListModelLoader.load(ListModelLoader.java:37)
at com.raizlabs.android.dbflow.sql.queriable.ListModelLoader.load(ListModelLoader.java:15)
at com.raizlabs.android.dbflow.sql.queriable.ModelLoader.load(ModelLoader.java:36)
at com.raizlabs.android.dbflow.sql.queriable.ListModelLoader.load(ListModelLoader.java:25)
at com.raizlabs.android.dbflow.sql.language.BaseModelQueriable.queryList(BaseModelQueriable.java:61)
at com.raizlabs.android.dbflow.sql.language.Where.queryList(Where.java:236)
at com.construct.v2.db.dao.TaskDao.read(TaskDao.java:39)
at com.construct.v2.providers.TaskProvider.readCached(TaskProvider.java:62)
at com.construct.v2.providers.TaskProvider.read(TaskProvider.java:54)
at com.construct.v2.viewmodel.entities.tasks.TasksViewModel.load(TasksViewModel.java:37)
at com.construct.v2.viewmodel.entities.AbstractEntitiesViewModel.subscribe(AbstractEntitiesViewModel.java:76)
at com.construct.v2.fragments.entities.TasksFragment.onViewCreated(TasksFragment.java:82)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1314)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1528)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1595)
at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:758)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2363)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2149)
at android.support.v4.app.FragmentManagerImpl.optimizeAndExecuteOps(FragmentManager.java:2103)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2013)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:710)
at android.os.Handler.handleCallback(Handler.java:815)
at android.os.Handler.dispatchMessage(Handler.java:104)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5624)
at java.lang.reflect.Method.invoke(Method.java)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:959)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:754)