Search code examples
android-sqliteandroid-roomandroid-jetpack

migrate to room give me Migration didn't properly handle but not diffrent


I am changing existing database to Room and facing this error:

 App has crashed, executing CustomActivityOnCrash's UncaughtExceptionHandler
java.lang.IllegalStateException: Migration didn't properly handle: tb_installment(ir.esfandune.wave.compose.model.Installment).
  Expected:
TableInfo{name='tb_installment', columns={Installment_id=Column{name='Installment_id', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=1, defaultValue='null'}, Installment_amount=Column{name='Installment_amount', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, installment_loadID=Column{name='installment_loadID', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='null'}, installment_number=Column{name='installment_number', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='null'}, Installment_maturityDate=Column{name='Installment_maturityDate', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, Installment_calculateAstrans=Column{name='Installment_calculateAstrans', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='0'}, Installment_payedCard_id=Column{name='Installment_payedCard_id', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='-1'}, Installment_paystatus=Column{name='Installment_paystatus', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='0'}, Installment_desc=Column{name='Installment_desc', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, Installment_catID=Column{name='Installment_catID', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='1'}, Installment_payDate=Column{name='Installment_payDate', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}}, foreignKeys=[], indices=[]}
 Found:
TableInfo{name='tb_installment', columns={Installment_id=Column{name='Installment_id', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=1, defaultValue='null'}, Installment_amount=Column{name='Installment_amount', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, installment_number=Column{name='installment_number', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='null'}, Installment_maturityDate=Column{name='Installment_maturityDate', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, Installment_calculateAstrans=Column{name='Installment_calculateAstrans', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='0'}, Installment_payedCard_id=Column{name='Installment_payedCard_id', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='-1'}, Installment_paystatus=Column{name='Installment_paystatus', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='0'}, Installment_desc=Column{name='Installment_desc', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, Installment_loadID=Column{name='Installment_loadID', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='null'}, Installment_catID=Column{name='Installment_catID', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='1'}, Installment_payDate=Column{name='Installment_payDate', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}}, foreignKeys=[], indices=[]}
    at androidx.room.RoomOpenHelper.onUpgrade(RoomOpenHelper.java:103)
    at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.onUpgrade(FrameworkSQLiteOpenHelper.java:183)
    at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:416)
    at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:316)

but doesn't exisit any diffrent between Expected AND Found


Solution

  • If you look carefully then there is a difference:-

    Expected has:-

    name='installment_loadID', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='null'
    

    Found's equivalent is :-

    name='Installment_loadID', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='null'
    

    i.e. the column name is capitalised in the found but not in the expected. Room is not at all forgiving even SQLite's component names are not case sensitive.

    It is suggested to always base the change(s) applied via migration on the SQL that exists in the createAllTables method of the generated java, which you can copy and paste. The generated java is visible via the Android View and will be in the class that is the same name, but suffixed with _Impl, as the class(es) annotated with @Database, after compiling/building the project.

    i.e. make the changes to the @Entity annotated class(es), and @Database annotated class(es) and then compile/build the project and then view the generated java copying the respective SQL into the Migration.