Room database bug report Created Tuesday 01 April ...
# android
v
Room database bug report Created Tuesday 01 April 2025 I'm hitting a problem using Room with a pre-packaged SQLite database. Here is the schema of the single table I'm trying to work with, copy-pasted from the SQLIte3 CLI:
SQLite version 3.37.2 2022-01-06 13:25:41
Enter ".help" for usage hints.
sqlite> .schema product
CREATE TABLE IF NOT EXISTS "product" (
"id"	INTEGER NOT NULL,
"slug"	TEXT NOT NULL UNIQUE,
"label"	TEXT NOT NULL UNIQUE,
"price"	NUMERIC NOT NULL,
PRIMARY KEY("id" AUTOINCREMENT)
);
Here are my entity definition corresponding to this table, the DAO to access it, the
ViewModel
and the database setup:
@Entity(tableName = "product")
data class Product(
@PrimaryKey(autoGenerate = true)
val id: Int,
val slug: String,
val label: String,
val price: Double,
@Ignore val quantity: Int,
) {
constructor(id: Int, slug: String, label: String, price: Double) : this(id, slug, label, price, 0)
}
@Dao
interface ProductData {
@Query("SELECT * FROM product")
fun getAllProducts(): List<Product>
}
class ProductViewModel(private val data: ProductData) : ViewModel() {
val products = data.getAllProducts()
}
@Database(
version = 1,
entities = [Product::class],
exportSchema = false,
)
abstract class AppDatabase : RoomDatabase() {
abstract val product: ProductData
companion object {
@Volatile
private var INSTANCE: AppDatabase? = null
fun getInstance(context: Context): AppDatabase {
synchronized(this) {
return INSTANCE ?: Room.databaseBuilder(
context.applicationContext,
AppDatabase::class.java,
"viscount.db"
)
.createFromAsset("data/viscount.db")
.build().also { INSTANCE = it }
}
}
}
}
here is how I set it up in my main activity:
class MainActivity : ComponentActivity() {
private val db by lazy { AppDatabase.getInstance(this) }
private val viewModel by viewModels<ProductViewModel>(
factoryProducer = {
object : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return ProductViewModel(db.product) as T
}
}
}
)
// other code omitted for brevity
}
The error occurs on the line
return ProductViewModel(db.product) as T
and here is a partial log from LogCat:
java.lang.IllegalStateException: Pre-packaged database has an invalid schema: product(com.red_dove.viscount.Product).
Expected:
TableInfo{name='product', columns={id=Column{name='id', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=1, defaultValue='undefined'}, label=Column{name='label', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='undefined'}, slug=Column{name='slug', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='undefined'}, price=Column{name='price', type='REAL', affinity='4', notNull=true, primaryKeyPosition=0, defaultValue='undefined'}}, foreignKeys=[], indices=[]}
Found:
TableInfo{name='product', columns={id=Column{name='id', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=1, defaultValue='undefined'}, slug=Column{name='slug', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='undefined'}, label=Column{name='label', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='undefined'}, price=Column{name='price', type='NUMERIC', affinity='1', notNull=true, primaryKeyPosition=0, defaultValue='undefined'}}, foreignKeys=[], indices=[]}
at androidx.room.RoomOpenHelper.onCreate(RoomOpenHelper.kt:73)
at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.onCreate(FrameworkSQLiteOpenHelper.kt:244)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:432)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:336)
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:632)
at androidx.room.RoomDatabase.assertNotSuspendingTransaction(RoomDatabase.kt:451)
at com.red_dove.viscount.ProductData_Impl.getAllProducts(ProductData_Impl.java:31)
at com.red_dove.viscount.ProductViewModel.<init>(Data.kt:33)
at com.red_dove.viscount.MainActivity$viewModel$2$1.create(MainActivity.kt:27)
The only relevant difference I can see in the "expected" vs "found" lines is that we're expecting
id=Column{name='id', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=1, defaultValue='undefined'}
but finding
id=Column{name='id', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=1, defaultValue='undefined'}
Can anyone explain why it finds
notNull=false
when by the table definiion clearly it should be marked as
notNull=true
, the expected value?
🧵 3
🧵 2
🙅 3
🚫 2
not kotlin but kotlin colored 4
s
Are you exported your Room schema as a JSON? What does your generated schema's
CREATE TABLE IF NOT EXISTS "product"
string look like?
c
1. Please post long code code snippets in the thread. 2. this is a slack workspace for the Kotlin programming language. 3. Your Android/Google question is off topic here.
Image from iOS.jpg
s
not even going to redirect them to #C7KS458SJ? 🙁
🤷🏼 1
c
Not much going on there so I doubt they’ll get answers there.
1
v
@Chrimaeon Sorry, I didn't realize it would be OT here ... @Seri I didn't export the schema. Not sure where I'd get the CREATE TABLE from the generated schema. OK, I'll hop over to Discord, thanks for your time.
w
send your architcure for project if use remote data source or local data you or both ,you should create repository and inmplemnete it layer of data use a clean architcure i didn't see the reposorty dependency in view model used in domain layer ,the reposotry and suspended fun for http call and i advise you to use dagger hilt
👎🏼 1
c
What does your suggestion have to do with a failing room schema validation? 🤣
s
Go ahead and export your schema, then search it for
"createSql"
to find the generated query
b
It looks like where you are creating the table, the price should be REAL and not NUMERIC, I think.