我有以下实体:
@Entity(tableName = "game_regions",
primaryKeys = {"_game", "_region_area"},
foreignKeys = {
@ForeignKey(
entity = GameEntity.class,
parentColumns = "_id",
childColumns = "_game"
),
@ForeignKey(
entity = RegionAreaEntity.class,
parentColumns = "_id",
childColumns = "_region_area"
)})
public class GameRegionsEntity {
@NonNull
@ColumnInfo(name = "_game")
private String game;
@NonNull
@ColumnInfo(name = "_region_area")
private String regionArea;
public GameRegionsEntity(@NonNull String game, @NonNull String regionArea) {
this.game = game;
this.regionArea = regionArea;
}
@NonNull
public String getGame() {
return game;
}
public void setGame(@NonNull String game) {
this.game = game;
}
@NonNull
public String getRegionArea() {
return regionArea;
}
public void setRegionArea(@NonNull String regionArea) {
this.regionArea = regionArea;
}
}
在SQL中以这种方式表示:
CREATE TABLE "game_regions" (
"_game" TEXT NOT NULL,
"_region_area" TEXT NOT NULL,
PRIMARY KEY("_game","_region_area"),
FOREIGN KEY("_region_area") REFERENCES "region_areas"("_id"),
UNIQUE("_game","_region_area"),
FOREIGN KEY("_game") REFERENCES "games"("_id")
);
当使用Android 6或更高版本的设备时,一切正常,没有任何错误,但是,当使用Android Lollipop 5.1时,它在架构首次验证时抛出以下异常:
java.lang.IllegalStateException: Pre-packaged database has an invalid schema: game_regions(GameRegionsEntity).
Expected:
TableInfo{name='game_regions', columns={_region_area=Column{name='_region_area', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=2, defaultValue='undefined'}, _game=Column{name='_game', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=1, defaultValue='undefined'}}, foreignKeys=[ForeignKey{referenceTable='games', onDelete='NO ACTION +', onUpdate='NO ACTION', columnNames=[_game], referenceColumnNames=[_id]}, ForeignKey{referenceTable='region_areas', onDelete='NO ACTION +', onUpdate='NO ACTION', columnNames=[_region_area], referenceColumnNames=[_id]}], indices=[]}
Found:
TableInfo{name='game_regions', columns={_game=Column{name='_game', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=1, defaultValue='undefined'}, _region_area=Column{name='_region_area', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=1, defaultValue='undefined'}}, foreignKeys=[ForeignKey{referenceTable='region_areas', onDelete='NO ACTION +', onUpdate='NO ACTION', columnNames=[_region_area], referenceColumnNames=[_id]}, ForeignKey{referenceTable='games', onDelete='NO ACTION +', onUpdate='NO ACTION', columnNames=[_game], referenceColumnNames=[_id]}], indices=null}
如果我们比较EXPECTED
和FOUND
模式的结果:我们注意到唯一的变化是两个主键的primaryKeyPosition
都是 * 1 *。
我不知道是什么导致了这个错误,为什么这是崩溃只在Android棒棒糖5.1(SDK 22)和它的工作在每个版本从23直到33.
有什么提示吗?
1条答案
按热度按时间kt06eoxx1#
我建议不要为资产提供/使用您的SQL,而是使用房间创建的SQL。
Room SQL为 (来自测试):-
1.您可能希望在您最喜欢的SQLite工具中,通过以下方式转换现有的资产数据库:
@Database
但后缀为**_Impl
**的类同名的类createAllTables
**方法,该方法包含预期表的实际SQL (注意,Room注解不直接支持UNIQUE约束)。INSERT INTO game_regions SELECT * FROM game_regions_renamed
***(未测试)***最初,使用您的代码加上以下支持代码(以模仿您未提供的代码)创建的项目:
createFromAsset
方法调用已删除,并在API 22设备(Android Studio中的模拟器)上运行。它运行良好。因此消除了API 22明显与Room不兼容的任何问题。应用程序被卸载,
createFromAsset
被恢复。使用Navicat(一个SQLite工具)创建了数据库,其中包含两个支持表(GameEntity和RegionAreaEnntity,使用由room生成的SQL):-运行SQL:-
已储存资料库(关闭资料库及连线,然后退出Navicat)。已将文件复制到assets文件夹(将文件重命名为_database. db)。运行应用程序并:-
已卸载应用程序。在Navicat(Room的SQL)中使用以下命令:-
导致:-
关闭数据库和连接并退出Navicat。已将数据库复制到assets目录(重命名以前使用的db文件)。运行了应用程序,运行正常。设备浏览器显示(应用程序检查仅适用于API 26+):-
最后,显示生成的java(以及资产):