Reputation: 61
I have a version 1 database with an int column. In version 2, I want to make my column nullable, to achieve this I have changed my column data type to Integer from int in my java entity class.
Since after some research I realized it's not possible to change just the data type of a column.
Here what I am doing in my migration method:
My original entity name is TaskEntity, I am creating a new temp table, copying the data and then dropping the original table and then renaming the temp table to original table.
database.execSQL(
"BEGIN TRANSACTION;" +
"CREATE TABLE TaskEntityNew('id' INTEGER PRIMARY KEY AUTOINCREMENT," +
"'text' TEXT," +
"'caseid' INTEGER NULL," +
"'status' INTEGER NOT NULL DEFAULT 0," +
"'datetime' DATETIME," +
",'updateDt' DATETIME," +
" FOREIGN KEY (caseid) REFERENCES CaseEntity(id));" +
"INSERT INTO TaskEntityNew(text,caseid,status,datetime,updateDt) SELECT text,caseid,status,datetime,update FROM TaskEntity;"+
"DROP TABLE TaskEntity;" +
"ALTER TABLE 'TaskEntityNew' RENAME TO 'TaskEntity';" +
"COMMIT;"
);
But I am getting this error
Caused by: java.lang.IllegalStateException: Migration didn't properly handle TaskEntity(EntityCollection.TaskEntity).
Expected:
TableInfo{name='TaskEntity', columns={text=Column{name='text', type='TEXT', notNull=false, primaryKeyPosition=0}, updateDt=Column{name='updateDt', type='INTEGER', notNull=false, primaryKeyPosition=0}, datetime=Column{name='datetime', type='INTEGER', notNull=false, primaryKeyPosition=0}, status=Column{name='status', type='INTEGER', notNull=true, primaryKeyPosition=0}, caseid=Column{name='caseid', type='INTEGER', notNull=false, primaryKeyPosition=0}, id=Column{name='id', type='INTEGER', notNull=true, primaryKeyPosition=1}}, foreignKeys=[ForeignKey{referenceTable='CaseEntity', onDelete='CASCADE', onUpdate='NO ACTION', columnNames=[caseid], referenceColumnNames=[id]}], indices=[Index{name='index_TaskEntity_caseid', unique=false, columns=[caseid]}]}
Found:
TableInfo{name='TaskEntity', columns={text=Column{name='text', type='TEXT', notNull=false, primaryKeyPosition=0}, updateDt=Column{name='updateDt', type='INTEGER', notNull=false, primaryKeyPosition=0}, datetime=Column{name='datetime', type='INTEGER', notNull=false, primaryKeyPosition=0}, status=Column{name='status', type='INTEGER', notNull=true, primaryKeyPosition=0}, caseid=Column{name='caseid', type='INTEGER', notNull=true, primaryKeyPosition=0}, id=Column{name='id', type='INTEGER', notNull=true, primaryKeyPosition=1}}, foreignKeys=[ForeignKey{referenceTable='CaseEntity', onDelete='CASCADE', onUpdate='NO ACTION', columnNames=[caseid], referenceColumnNames=[id]}], indices=[Index{name='index_TaskEntity_caseid', unique=false, columns=[caseid]}]}
What I can think of a problem is that my SQL block is not executing and my old table data is trying to match with the old java entity class. Any help will be appreciated!
Upvotes: 5
Views: 4446
Reputation: 408
According to the documentation, execSQL
only executes a single SQL statement:
the SQL statement to be executed. Multiple statements separated by semicolons are not supported.
so you need to rewrite your code into multiple calls like:
database.execSQL("BEGIN TRANSACTION;");
database.execSQL("CREATE TABLE TaskEntityNew('id' INTEGER PRIMARY KEY AUTOINCREMENT," +
"'text' TEXT," +
"'caseid' INTEGER NULL," +
"'status' INTEGER NOT NULL DEFAULT 0," +
"'datetime' DATETIME," +
",'updateDt' DATETIME," +
" FOREIGN KEY (caseid) REFERENCES CaseEntity(id));");
database.execSQL("INSERT INTO TaskEntityNew(text,caseid,status,datetime,updateDt) SELECT text,caseid,status,datetime,update FROM TaskEntity;");
database.execSQL("DROP TABLE TaskEntity;");
database.execSQL("ALTER TABLE 'TaskEntityNew' RENAME TO 'TaskEntity';");
database.execSQL("COMMIT;");
As-is, SQLite is executing "BEGIN TRANSACTION;" then ignoring the rest of your SQL statements.
Upvotes: 4