英文:
Room migration adding column fail
问题
以下是您要的翻译:
在这个类中:
data class UserEntity(
@PrimaryKey var uid: String,
var name: String?,
var photo: String?,
var status: Int = 0,
var interaction: Long? = null,
var additional: String? = ""
)
尝试运行迁移时:
private val MIGRATION_1_2 = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE UserEntity ADD COLUMN additional TEXT NOT NULL DEFAULT ''")
}
}
我遇到了问题:
Caused by: java.lang.IllegalStateException: 迁移没有正确处理:UserEntity(com.michlindevelopment.way.mainapp.database.UserEntity)。
预期:
TableInfo{name='UserEntity', columns={name=Column{name='name', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='undefined'}, interaction=Column{name='interaction', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='undefined'}, uid=Column{name='uid', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=1, defaultValue='undefined'}, photo=Column{name='photo', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='undefined'}, status=Column{name='status', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='undefined'}, additional=Column{name='additional', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='undefined'}}, foreignKeys=[], indices=[]}
找到:
TableInfo{name='UserEntity', columns={uid=Column{name='uid', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=1, defaultValue='undefined'}, name=Column{name='name', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='undefined'}, photo=Column{name='photo', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='undefined'}, status=Column{name='status', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='undefined'}, interaction=Column{name='interaction', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='undefined'}, additional=Column{name='additional', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue=''''}}, foreignKeys=[], indices=[]}
可能是顺序有问题吗?
我预期name列在前,但在找到的表中,uid在前。
英文:
I this class:
data class UserEntity(
@PrimaryKey var uid: String,
var name: String?,
var photo: String?,
var status: Int = 0,
var interaction: Long? = null,
var additional: String? = ""
)
When trying to run migration:
private val MIGRATION_1_2 = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE UserEntity ADD COLUMN additional TEXT NOT NULL DEFAULT ''")
}
}
I get:
Caused by: java.lang.IllegalStateException: Migration didn't properly handle: UserEntity(com.michlindevelopment.way.mainapp.database.UserEntity).
Expected:
TableInfo{name='UserEntity', columns={name=Column{name='name', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='undefined'}, interaction=Column{name='interaction', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='undefined'}, uid=Column{name='uid', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=1, defaultValue='undefined'}, photo=Column{name='photo', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='undefined'}, status=Column{name='status', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='undefined'}, additional=Column{name='additional', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='undefined'}}, foreignKeys=[], indices=[]}
Found:
TableInfo{name='UserEntity', columns={uid=Column{name='uid', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=1, defaultValue='undefined'}, name=Column{name='name', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='undefined'}, photo=Column{name='photo', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='undefined'}, status=Column{name='status', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='undefined'}, interaction=Column{name='interaction', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='undefined'}, additional=Column{name='additional', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue=''''}}, foreignKeys=[], indices=[]}
There is problem with the order maybe?
I expected the name column is first, in found uid is first
答案1
得分: 1
代码部分不翻译。以下是内容的翻译:
The order of the columns is not an issue.
列的顺序不是问题。
There are issues with the new column as per the expected is :-
根据期望,新列存在问题:
additional=Column{name='additional', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='undefined'}}
additional=Column{name='additional', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue=''''
i.e. Room (according to the @Entity
definition) is that:-
即,根据 @Entity
定义,Room 是这样的:
-
a) Room expects no
NOT NULL
i.e. nulls are allowed as pervar additional: String? = ""
i.e. the?
says that the value is nullable.
a) Room 不期望有NOT NULL
,即根据var additional: String? = ""
,允许空值,?
表示该值可为空。 -
b) Room expects no
DEFAULT
, whilst theDEFAULT
value is an empty String as perDEFAULT ''
and thusdefaultValue=''''
b) Room 不期望有DEFAULT
,而DEFAULT
值是一个空字符串,如DEFAULT ''
,因此defaultValue=''''
To fix the issues above you should use:-
要解决上述问题,您应该使用:
ALTER TABLE UserEntity ADD COLUMN additional TEXT
- note the assumption is that no other changes have been made other than adding this column and thus that other column comparisons between expected and found have not been looked at (also that the recommended way is as described below)
- 请注意,假设除了添加此列外,没有进行其他更改,因此没有查看期望和实际之间的其他列比较(还建议如下描述的方式)
i.e. remove the NOT NULL and have no DEFAULT and thus the default will be null.
即,去掉 NOT NULL 并且没有 DEFAULT,因此默认值将为 null。
However, the easier way to avoid issues with Room's expectations is to let Room tell you exactly what it expects, as it creates the SQL used to create the tables whenever you compile the project if the entities parameter of the @Database
annotation includes the @Entity
annotated class.
然而,避免与 Room 的期望产生问题的更简单方法是让 Room 告诉您它期望的内容,因为每当编译项目时,如果 @Database
注解的 entities 参数包括带有 @Entity
注解的类,它就会创建用于创建表的 SQL。
So to get the exact column definition, you:-
因此,要获取确切的列定义,您可以:
- compile the project after making the changes.
在进行更改后编译项目。 - Using Android View find the java (generated)
使用 Android View 找到 java (generated) - Find the class that is the same name as the
@Database
annotated class but suffixed with_Impl
.
找到与@Database
注解的类同名但后缀为_Impl
的类。 - Find the method/function on the class that is named
createAllTables
.
在该类中找到名为createAllTables
的方法/函数。 - The SQL for the creation of the table and thus the column definitions will be within the method.
表的创建 SQL 和列定义将在该方法中。
Note if you need a DEFAULT value then you need to specify this in the defaultValue
parameter of the @ColumnInfo
annotation (otherwise the expected but found issue). Furthermore if the column has the NOT NULL constraint then a default value is required as it cannot be null as per
请注意,如果您需要默认值,那么您需要在 @ColumnInfo
注解的 defaultValue
参数中指定它(否则将出现期望与实际问题)。此外,如果列具有 NOT NULL 约束,则需要默认值,因为它不能为 null,如下所述:
If a NOT NULL constraint is specified, then the column must have a default value other than NULL.
如果指定了 NOT NULL 约束,则该列必须具有非 NULL 的默认值。
英文:
The order of the columns is not an issue.
There are issues with the new column as per the expected is :-
additional=Column{name='additional', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='undefined'}}
and the found is
additional=Column{name='additional', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue=''''
i.e. Room (according to the @Entity
definition) is that:-
- a) Room expects no
NOT NULL
i.e. nulls are allowed as pervar additional: String? = ""
i.e. the?
says that the value is nullable. - b) Room expects no
DEFAULT
, whilst theDEFAULT
value is an empty String as perDEFAULT ''
and thusdefaultValue=''''
To fix the issues above you should use:-
ALTER TABLE UserEntity ADD COLUMN additional TEXT
- note the assumption is that no other changes have been made other than adding this column and thus that other column comparisons between expected and found have not been looked at (also that the recommended way is as described below)
i.e. remove the NOT NULL and have no DEFAULT and thus the default will be null.
However, the easier way to avoid issues with Room's expectations is to let Room tell you exactly what it expects, as it creates the SQL used to create the tables whenever you compile the project if the entities parameter of the @Database
annotation includes the @Entity
annotated class.
So to get the exact column definition, you:-
- compile the project after making the changes.
- Using Android View find the java (generated)
- Find the class that is the same name as the
@Database
annotated class but suffixed with_Impl
. - Find the method/function on the class that is named
createAllTables
. - The SQL for the creation of the table and thus the column definitions will be within the method.
Note if you need a DEFAULT value then you need to specify this in the defaultValue
parameter of the @ColumnInfo
annotation (otherwise the expected but found issue). Furthermore if the column has the NOT NULL constraint then a default value is required as it cannot be null as per
> If a NOT NULL constraint is specified, then the column must have a default value other than NULL.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论