我尝试使用预填充的Room数据库,但在尝试使用该数据库时出现崩溃,并出现以下错误:java.lang.NullPointerException: cursor.getString(toColumnIndex) must not be null
在我添加createFromAsset("databses/test.db")
方法之前,一切都很正常,但当它崩溃时。如果我不执行getAllCocktails()
方法,就不会崩溃。我已经检查了我插入的数据库是否都是一样的,我找不到任何差异(我还检查了数据是否用AppInspection加载)
我不仅测试了getAllCocktails()
,还尝试了使用完全参数化的构造函数插入
我将张贴(一些)我的代码和日志,以便更容易诊断我尝试与房间的版本2.5.1和2.5.2
test.db文件
活动内容:
public class PedirTragoActivity extends AppCompatActivity {
AppDatabase db;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pedir_trago1_1);
db = AppDatabase.getInstance(this.getApplication());
db.cocktailDAO().getAllCocktails();
}
}
房间数据库:
@Database(entities = {
BottleEntity.class,
BottleIngredientEntity.class,
CocktailEntity.class,
CocktailIngredientEntity.class,
IngredientTypeEntity.class
},
version = 7)
public abstract class AppDatabase extends RoomDatabase {
public static AppDatabase INSTANCE;
public abstract BottleDAO bottleDAO();
public abstract BottleIngredientDAO bottleIngredientDAO();
public abstract CocktailDAO cocktailDAO();
public abstract CocktailIngredientDAO cocktailIngredientDAO();
public abstract IngredientTypeDAO ingredientTypeDAO();
public static AppDatabase getInstance(Context context) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context, AppDatabase.class, "barbotApp.db")
.allowMainThreadQueries()
.fallbackToDestructiveMigration()
.createFromAsset("databases/test.db")
.build();
}
return INSTANCE;
}
}
瓶实体:
@Entity(tableName = "bottles")
public class BottleEntity {
@PrimaryKey
@NonNull
private int position;//Del 0 al 7 son alcoholes, el 8 es shaker y del 9 al 16 son mezclas
private String name;
@NonNull
private int capacity;
@NonNull
private int currentAmount;
public BottleEntity() {
}
public BottleEntity(int position, String name, int capacity, int currentAmount) {
this.position = position;
this.name = name;
this.capacity = capacity;
this.currentAmount = currentAmount;
}
@Ignore
public BottleEntity(int position, String name, int capacity) {
this.position = position;
this.name = name;
this.capacity = capacity;
this.currentAmount = capacity;
}
public int getPosition() {
return position;
}
public void setPosition(int position) {
this.position = position;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getCapacity() {
return capacity;
}
public void setCapacity(int capacity) {
this.capacity = capacity;
}
public int getCurrentAmount() {
return currentAmount;
}
public void setCurrentAmount(int currentAmount) {
this.currentAmount = currentAmount;
}
}
瓶成分实体:
@Entity(tableName = "bottle_ingredient",
foreignKeys = {
@ForeignKey(entity = BottleEntity.class, parentColumns = "position", childColumns = "bottlePos"),
@ForeignKey(entity = IngredientTypeEntity.class, parentColumns = "id", childColumns = "ingredientId")
})
public class BottleIngredientEntity {
@PrimaryKey(autoGenerate = true)
@NonNull
private int id;
@NonNull
private int bottlePos;
@NonNull
private int ingredientId;
public BottleIngredientEntity() {
}
public BottleIngredientEntity(int bottlePos, int ingredientId) {
this.bottlePos = bottlePos;
this.ingredientId = ingredientId;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getBottlePos() {
return bottlePos;
}
public void setBottlePos(int bottlePos) {
this.bottlePos = bottlePos;
}
public int getIngredientId() {
return ingredientId;
}
public void setIngredientId(int ingredientId) {
this.ingredientId = ingredientId;
}
}
CocktailIngredientEntity:
@Entity(tableName = "cocktail_ingredients",
foreignKeys = {
@ForeignKey(entity = IngredientTypeEntity.class, parentColumns = "id", childColumns = "typeId"),
@ForeignKey(entity = CocktailEntity.class, parentColumns = "id", childColumns = "cocktailId")
})
public class CocktailIngredientEntity {
@PrimaryKey(autoGenerate = true)
@NonNull
private int id;
@NonNull
private int typeId;
@NonNull
private int quantity;
@NonNull
private int cocktailId;
public CocktailIngredientEntity(int typeId, int quantity, int cocktailId) {
this.typeId = typeId;
this.quantity = quantity;
this.cocktailId = cocktailId;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getTypeId() {
return typeId;
}
public void setTypeId(int typeId) {
this.typeId = typeId;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
public int getCocktailId() {
return cocktailId;
}
public void setCocktailId(int cocktailId) {
this.cocktailId = cocktailId;
}
}
成分类型实体:
@Entity(tableName = "ingredient_types")
public class IngredientTypeEntity {
@PrimaryKey(autoGenerate = true)
@NonNull
private int id;
private String name;
public IngredientTypeEntity() {
}
public IngredientTypeEntity(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
鸡尾酒实体:
@Entity(tableName = "cocktails")
public class CocktailEntity {
@PrimaryKey(autoGenerate = true)
@NonNull
private int id;
private String name;
@NonNull
private boolean isOnStock;
@NonNull
private boolean hasIce;
private String imgName;
public CocktailEntity(String name, boolean isOnStock, boolean hasIce, String imgName) {
this.name = name;
this.isOnStock = isOnStock;
this.hasIce = hasIce;
this.imgName = imgName;
}
@Ignore
public CocktailEntity(String name, boolean hasIce, String imaName) {
this.name = name;
this.isOnStock = false;
this.hasIce = hasIce;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isOnStock() {
return isOnStock;
}
public void setOnStock(boolean onStock) {
isOnStock = onStock;
}
public boolean isHasIce() {
return hasIce;
}
public void setHasIce(boolean hasIce) {
this.hasIce = hasIce;
}
public String getImgName() {
return imgName;
}
public void setImgName(String imgName) {
this.imgName = imgName;
}
}
鸡尾酒道:
@Dao
public interface CocktailDAO {
@Insert
long insertCocktail(CocktailEntity cocktail);
@Query("SELECT id FROM cocktails WHERE name = :name")
int getCocktailId(String name);
@Query("SELECT c.* FROM cocktails AS c WHERE c.id = :id")
CocktailEntity getCocktail(int id); //Need to use a repository, separate this 2 parts
@Query("SELECT * FROM cocktails")
List<CocktailEntity> getAllCocktails();
@Query("SELECT cocktails.id FROM cocktails")
List<Integer> getAllCocktailIds();
@Query("SELECT * FROM cocktails" +
" WHERE cocktails.isOnStock = 1")
List<CocktailEntity> getAllCocktailsInStock();
@Query("SELECT isOnStock FROM cocktails WHERE id = :id")
boolean isCocktailInStock(int id);
@Query("UPDATE cocktails SET isOnStock = :isOnStock WHERE id = :id")
void updateCocktailStock(int id, boolean isOnStock);
}
Logcat:
2023-09-23 17:17:20.600 8250-8250 Choreographer com.mecatronica.barbot I Skipped 67 frames! The application may be doing too much work on its main thread.
2023-09-23 17:17:20.801 8250-8594 AdrenoGLES-0 com.mecatronica.barbot I QUALCOMM build : 03e27f8, I326e6aff90
Build Date : 11/02/20
OpenGL ES Shader Compiler Version: EV031.32.02.04
Local Branch : mybrancheb1d781c-1a78-f1f4-8c78-ac1f6bcc2cee
Remote Branch : quic/gfx-adreno.lnx.1.0.r116-rel
Remote Branch : NONE
Reconstruct Branch : NOTHING
2023-09-23 17:17:20.801 8250-8594 AdrenoGLES-0 com.mecatronica.barbot I Build Config : S P 10.0.7 AArch64
2023-09-23 17:17:20.801 8250-8594 AdrenoGLES-0 com.mecatronica.barbot I Driver Path : /vendor/lib64/egl/libGLESv2_adreno.so
2023-09-23 17:17:20.813 8250-8594 AdrenoGLES-0 com.mecatronica.barbot I PFP: 0x016ee190, ME: 0x00000000
2023-09-23 17:17:21.019 8250-8594 LB com.mecatronica.barbot E fail to open file: No such file or directory
2023-09-23 17:17:21.021 8250-8594 OpenGLRenderer com.mecatronica.barbot I Davey! duration=1547ms; Flags=1, IntendedVsync=42335033169415, Vsync=42336149836037, OldestInputEvent=9223372036854775807, NewestInputEvent=0, HandleInputStart=42336161943432, AnimationStart=42336162004370, PerformTraversalsStart=42336162065047, DrawStart=42336409293120, SyncQueued=42336445054213, SyncStart=42336445465515, IssueDrawCommandsStart=42336445624838, SwapBuffers=42336577074578, FrameCompleted=42336581385203, DequeueBufferDuration=272760, QueueBufferDuration=682187, GpuCompleted=1893829464,
2023-09-23 17:17:21.027 8250-8250 Looper com.mecatronica.barbot W PerfMonitor doFrame : time=424ms vsyncFrame=0 latency=1127ms procState=2 historyMsgCount=10 (msgIndex=1 wall=1223ms seq=4 running=1128ms runnable=12ms late=2999ms h=android.app.ActivityThread$H w=159) (msgIndex=5 wall=1007ms seq=8 running=2ms runnable=1ms io=4ms late=3591ms h=android.app.ActivityThread$H w=127)
2023-09-23 17:17:21.154 8250-8250 Looper com.mecatronica.barbot W PerfMonitor doFrame : time=35ms vsyncFrame=0 latency=459ms procState=2 historyMsgCount=4 (msgIndex=1 wall=424ms seq=14 running=255ms runnable=1ms late=1127ms h=android.view.Choreographer$FrameHandler c=android.view.Choreographer$FrameDisplayEventReceiver) (msgIndex=4 wall=78ms seq=17 running=70ms runnable=2ms late=413ms h=android.view.ViewRootImpl$ViewRootHandler c=androidx.appcompat.app.AppCompatDelegateImpl$2)
2023-09-23 17:17:28.708 8250-8250 MiuiFrameworkFactory com.mecatronica.barbot V get AllImpl object = android.common.MiuiFrameworkFactoryImpl@b038154
2023-09-23 17:17:28.726 8250-8250 MirrorManager com.mecatronica.barbot W this model don't Support
2023-09-23 17:17:28.773 8250-8250 Timeline com.mecatronica.barbot I Timeline: Activity_launch_request time:42344334
2023-09-23 17:17:28.996 8250-8250 DecorView[] com.mecatronica.barbot D getWindowModeFromSystem windowmode is 1
2023-09-23 17:17:28.997 8250-8250 DecorView com.mecatronica.barbot D createDecorCaptionView windowingMode:1 mWindowMode 1 isFullscreen: true
2023-09-23 17:17:30.631 8250-8250 AndroidRuntime com.mecatronica.barbot D Shutting down VM
2023-09-23 17:17:30.646 8250-8250 AndroidRuntime com.mecatronica.barbot E FATAL EXCEPTION: main
Process: com.mecatronica.barbot, PID: 8250
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mecatronica.barbot/com.mecatronica.barbot.PedirTragoActivity}: java.lang.NullPointerException: cursor.getString(toColumnIndex) must not be null
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3550)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3710)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2146)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:236)
at android.app.ActivityThread.main(ActivityThread.java:8057)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:656)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:967)
Caused by: java.lang.NullPointerException: cursor.getString(toColumnIndex) must not be null
at androidx.room.util.TableInfoKt.readForeignKeyFieldMappings(TableInfo.kt:536)
at androidx.room.util.TableInfoKt.readForeignKeys(TableInfo.kt:488)
at androidx.room.util.TableInfoKt.readTableInfo(TableInfo.kt:472)
at androidx.room.util.TableInfo$Companion.read(TableInfo.kt:130)
at androidx.room.util.TableInfo.read(Unknown Source:2)
at com.mecatronica.barbot.database.AppDatabase_Impl$1.onValidateSchema(AppDatabase_Impl.java:136)
at androidx.room.RoomOpenHelper.onCreate(RoomOpenHelper.kt:72)
at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.onCreate(FrameworkSQLiteOpenHelper.kt:244)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:411)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:316)
at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.getWritableOrReadableDatabase(FrameworkSQLiteOpenHelper.kt:232)
at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.innerGetDatabase(FrameworkSQLiteOpenHelper.kt:190)
at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.getSupportDatabase(FrameworkSQLiteOpenHelper.kt:151)
at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper.getWritableDatabase(FrameworkSQLiteOpenHelper.kt:104)
at androidx.room.SQLiteCopyOpenHelper.getWritableDatabase(SQLiteCopyOpenHelper.kt:71)
at androidx.room.RoomDatabase.inTransaction(RoomDatabase.kt:638)
at androidx.room.RoomDatabase.assertNotSuspendingTransaction(RoomDatabase.kt:457)
at com.mecatronica.barbot.database.daos.CocktailDAO_Impl.getAllCocktails(CocktailDAO_Impl.java:177)
at com.mecatronica.barbot.PedirTragoActivity.onCreate(PedirTragoActivity.java:63)
at android.app.Activity.performCreate(Activity.java:8157)
at android.app.Activity.performCreate(Activity.java:8129)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1310)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3523)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3710)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2146)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:236)
at android.app.ActivityThread.main(ActivityThread.java:8057)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:656)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:967)
2023-09-23 17:17:30.716 8250-8250 Process com.mecatronica.barbot I Sending signal. PID: 8250 SIG: 9
SQL转储表单test.db:
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE IF NOT EXISTS "ingredient_types"
(
id INTEGER not null
constraint ingredient_types_pk
primary key,
name TEXT
);
INSERT INTO ingredient_types VALUES(1,'SHAKE');
INSERT INTO ingredient_types VALUES(2,'limón');
INSERT INTO ingredient_types VALUES(3,'ron');
INSERT INTO ingredient_types VALUES(4,'tonica');
INSERT INTO ingredient_types VALUES(5,'ginebra');
INSERT INTO ingredient_types VALUES(6,'campari');
INSERT INTO ingredient_types VALUES(7,'naranja');
INSERT INTO ingredient_types VALUES(8,'fernet');
INSERT INTO ingredient_types VALUES(9,'coca');
INSERT INTO ingredient_types VALUES(10,'durazno');
INSERT INTO ingredient_types VALUES(11,'granadina');
INSERT INTO ingredient_types VALUES(12,'vodka');
CREATE TABLE IF NOT EXISTS "bottle_ingredient"
(
id INTEGER not null
constraint bottle_ingredient_pk
primary key,
bottlePos INTEGER not null
constraint bottle_ingredient_bottles_position_fk
references bottles,
ingredientId INTEGER not null
constraint bottle_ingredient_ingredient_types_id_fk
references ingredient_types
);
INSERT INTO bottle_ingredient VALUES(1,8,5);
INSERT INTO bottle_ingredient VALUES(2,9,6);
INSERT INTO bottle_ingredient VALUES(3,10,8);
INSERT INTO bottle_ingredient VALUES(4,11,3);
INSERT INTO bottle_ingredient VALUES(5,12,12);
INSERT INTO bottle_ingredient VALUES(7,0,2);
INSERT INTO bottle_ingredient VALUES(8,1,4);
INSERT INTO bottle_ingredient VALUES(9,2,7);
INSERT INTO bottle_ingredient VALUES(10,3,9);
INSERT INTO bottle_ingredient VALUES(11,4,10);
INSERT INTO bottle_ingredient VALUES(12,5,11);
INSERT INTO bottle_ingredient VALUES(13,16,1);
CREATE TABLE IF NOT EXISTS "bottles"
(
position INTEGER not null
constraint bottles_pk
primary key,
name TEXT,
capacity INTEGER not null,
currentAmount INTEGER not null
);
INSERT INTO bottles VALUES(0,'limon',2000,2000);
INSERT INTO bottles VALUES(1,'tonica',2000,2000);
INSERT INTO bottles VALUES(2,'naranja',2000,2000);
INSERT INTO bottles VALUES(3,'coca',2000,2000);
INSERT INTO bottles VALUES(4,'durazno',2000,2000);
INSERT INTO bottles VALUES(5,'granadina',2000,2000);
INSERT INTO bottles VALUES(6,'Mezcla 7',1,1);
INSERT INTO bottles VALUES(7,'Mezcla 8',1,1);
INSERT INTO bottles VALUES(8,'ginebra',700,700);
INSERT INTO bottles VALUES(9,'campari',750,750);
INSERT INTO bottles VALUES(10,'fernet',750,750);
INSERT INTO bottles VALUES(11,'ron',750,750);
INSERT INTO bottles VALUES(12,'vodka',700,700);
INSERT INTO bottles VALUES(13,'Bottle 6',1,1);
INSERT INTO bottles VALUES(14,'Bottle 7',1,1);
INSERT INTO bottles VALUES(15,'Bottle 8',1,1);
INSERT INTO bottles VALUES(16,'Shakeo',1000,1000);
CREATE TABLE IF NOT EXISTS "cocktail_ingredients"
(
id INTEGER not null
constraint cocktail_ingredients_pk
primary key,
typeId INTEGER not null
constraint cocktail_ingredients_ingredient_types_id_fk
references ingredient_types,
quantity INTEGER not null,
cocktailId INTEGER not null
constraint cocktail_ingredients_cocktails_id_fk
references cocktails
);
INSERT INTO cocktail_ingredients VALUES(1,6,60,1);
INSERT INTO cocktail_ingredients VALUES(2,7,136,1);
INSERT INTO cocktail_ingredients VALUES(3,9,146,2);
INSERT INTO cocktail_ingredients VALUES(4,8,50,2);
INSERT INTO cocktail_ingredients VALUES(5,5,60,3);
INSERT INTO cocktail_ingredients VALUES(6,4,136,3);
INSERT INTO cocktail_ingredients VALUES(7,3,50,4);
INSERT INTO cocktail_ingredients VALUES(8,9,120,4);
INSERT INTO cocktail_ingredients VALUES(9,2,10,4);
INSERT INTO cocktail_ingredients VALUES(10,12,40,5);
INSERT INTO cocktail_ingredients VALUES(11,10,20,5);
INSERT INTO cocktail_ingredients VALUES(12,7,40,5);
INSERT INTO cocktail_ingredients VALUES(13,1,30,5);
INSERT INTO cocktail_ingredients VALUES(14,11,40,5);
CREATE TABLE IF NOT EXISTS "cocktails"
(
id INTEGER not null
constraint cocktails_pk
primary key,
name TEXT,
isOnStock INTEGER not null,
hasIce INTEGER not null,
imgName TEXT
);
INSERT INTO cocktails VALUES(1,'campari',1,1,'campari');
INSERT INTO cocktails VALUES(2,'fernet',1,1,'fernet');
INSERT INTO cocktails VALUES(3,'gin tonic',1,1,'gintonic');
INSERT INTO cocktails VALUES(4,'ron cola',1,1,'roncola');
INSERT INTO cocktails VALUES(5,'sex On the beach',1,1,'sexOnTheBeach');
COMMIT;
1条答案
按热度按时间2lpgd9681#
在我添加createFromAsset(“databses/test.db”)方法之前,一切都很正常
然后从logcat:
cursor.getString(toColumnIndex)不能为null
可能是由于当
@Entity
注解类中的列不允许空值时,资产中的数据在列中具有空值(或至少一个空值)。还应该注意的是,如果排除
db.cocktailDAO().getAllCocktails();
,则数据库甚至不会被访问,因此甚至不会被创建。也就是说,只是获取数据库的示例并不打开数据库,而是延迟打开,直到尝试访问数据库。调查结果摘要
问题是,正如预测的那样,资产。然而,它与getAllCocktails方法无关,除了这是导致数据库打开的原因,因此是资产的副本,然后是数据库的打开。
在这种情况下,由于资产首先被复制到临时数据库,然后被复制到实际的房间数据库,因此异常是(据信)从资产到发生异常的实际数据库的复制。
实际问题是由于Room预期(实际需要)的数据库模式与资产模式之间的差异。
正如人们一直建议的那样,与其试图预测Room VERY STRICT模式需求,不如使用在成功编译项目后生成的可获得的模式。
有关如何解决此特定问题,请参阅下面的修复程序。
在您实际尝试检索数据之前,它不会成为一个问题,因此只有当您从资产中引入数据时才会出现问题。
你有两个选择:
1.修改
@Entity
注解类以允许列为空,或者1.修改源数据使其不包含空值。
你可以修改你的问题,包括:
@Entity
注解的类。@Dao
注解类。工作示例显示问题很可能与资产有关
使用您的代码创建了AS项目(而不是使用MainActivity而不是PedirTragoActivity),并将MainActivity更改为:-
在createFromAsset被注解掉的情况下运行了上述两次。日志显示前0个鸡尾酒,3个插入3个鸡尾酒后。第二次运行显示3和6。
请注意添加的close(这将强制提交WAL,因此只有一个文件)。
使用设备资源管理器将数据库文件复制到assets文件夹中,然后复制到assets/database文件夹中作为test.db,例如。:-
卸载的应用程序包括从资产中删除代码,并重新运行:-
结果日志:-
public CocktailEntity(String name, boolean hasIce, String imaName)
,因此imageName为null(并且这些为null不是问题)使用下载的mediafile test.db编辑
简而言之,这是很好的工作(在版本1和版本7)。
因此,问题似乎不是与提供的代码(数据库明智的),也不是与文件本身。
即在版本7,对于全新安装,则日志(根据上面的代码)导致:
因此,问题可能是两个应用程序之间的差异,这可能是很多。
at androidx.room.util.TableInfoKt.readForeignKeyFieldMappings(TableInfo.kt:536)
之后*kt可能表示Kotlin代码,对于Java App????
编辑新增实体
因此问题与IngredientTypeEntity/BottleIngredientEntity有关
因此,此问题似乎与BottlebottledientEntity有关。
在此阶段注解掉createFromAsset,以查看问题是否与模式有关,而不是与数据有关
db.getOpenHelper().getWritableDatabase();
以强制打开数据库。因此,问题很大程度上似乎是BottleIngredientEntity以及Room如何管理处理资产。使用临时数据库,然后复制该临时数据库。
资产为:-
房间是:-
建议修复
我的建议是放弃使用您目前拥有的资产,并使用工具(对Datagrip一无所知),您可以根据Room创建模式并相应地填充数据。
即:
1.编译项目,然后检查
java(generated)
(从Android Studio的Android View可见)1.找到AppDatabase_Impl类。
1.在类中找到createAllTables方法,复制创建表的SQL(不需要创建
room_master_table
,也不需要插入)。1.通过工具或SQL将数据库版本更改为版本7
1.根据需要填充表。
1.保存数据库以确保存在单个文件(即,no -wal或-shm文件)(例如,使用Navicat时,您必须关闭Navicat以使其完全提交)。
1.然后将此文件复制到资产中。
注意不要关闭外键,我怀疑列不能为空是由于您加载的数据中的无效引用,并且此异常是将资产从临时数据库复制到实际数据库的一部分。
获取CREATE SQL的示例:
最终修复
如上所述,我认为核心问题是您的资产数据库的SCHEMA与Room期望的不匹配但是由于将资产从临时初始副本复制到最终Room数据库时作为资产副本的一部分的异常,这被屏蔽了。
因此,修复方法是使用预期的模式,该模式的SQL在AppDatabase_Impl类的
createAllTables
方法中的generate java中可用(即后缀为_Impl的@Database
注解类)。要利用资产中的现有数据,则可以运行转换。这将重命名现有表,根据生成的SQL创建新表,然后从重命名的表中加载数据。此外,它会将user_version(数据库版本)设置为7(以确保回退不会清除数据库,因为似乎没有迁移,因此小于7的版本将期望迁移,但在不存在的情况下清除数据库)。
SQL脚本为:-
一旦转换(并检查正确/预期的数据),然后保存数据库文件,确保没有-wal或-shm文件(使用Navicat,您必须关闭/结束Navicat才能关闭文件)。然后将文件复制到资产中,一切都应该很好。
按照上述步骤操作后,卸载应用程序并运行日志(插入注解):-
使用App Inspection(运行查询)显示:-