Estou tentando usar um banco de dados Room pré-preenchido, mas recebo uma falha ao tentar usar o banco de dados com o seguinte erro: java.lang.NullPointerException: cursor.getString(toColumnIndex) must not be null
Tudo funciona bem até eu adicionar o createFromAsset("databses/test.db")
método, quando ele trava. Nada trava se eu simplesmente não executar o getAllCocktails()
método. Já verifiquei se o banco de dados que inseri é igual e não encontrei nenhuma diferença (também verifiquei se os dados são carregados com AppInspection)
Eu não apenas testei, getAllCocktails()
também tentei inserir com um construtor totalmente parametrizado
Vou postar (alguns) meus códigos e logs para que seja mais fácil diagnosticar. Tentei com as versões 2.5.1 e 2.5.2 do Room
arquivo teste.db
Atividade:
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();
}
}
Banco de dados da sala:
@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;
}
}
GarrafaEntidade:
@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;
}
}
BottleIngredientEntity:
@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;
}
}
CoquetelIngredienteEntidade:
@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;
}
}
EntidadeTipoIngrediente:
@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;
}
}
Entidade Coquetel:
@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;
}
}
Coquetel Dao:
@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 dump form 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;