对房间实体使用 kotlin.UByte 无效
Using kotlin.UByte for Room Entity not working
我想在我的房间数据库中存储以下数据class。不知何故,我没有成功:
@Entity
data class UInt8(
@PrimaryKey(autoGenerate = true)
var key: Int,
var name: String = "uint8-test",
var value: UByte = 0.toUByte(),
var size: Int = 1,
var readOnly: Boolean = true
)
我的自动生成的构建文件总是出错:
C:<...>\UInt8.java:15: error: Cannot find getter for field.
private byte value;
Cannot find getter for field.
UShort
、UInt
和 ULong
相同。
但是,如果我用 Int
替换它,它似乎可以工作,但不是我想要的(它需要是一个 UByte。
build.grade
(来自developer.android.com):
def room_version = "2.4.2"
//implementation "androidx.room:room-runtime:$room_version"
//annotationProcessor "androidx.room:room-compiler:$room_version"
implementation "androidx.room:room-ktx:$room_version"
kapt "androidx.room:room-compiler:2.5.0-alpha01"
// kapt "org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.2.0"
// optional - RxJava2 support for Room
implementation "androidx.room:room-rxjava2:$room_version"
// optional - RxJava3 support for Room
implementation "androidx.room:room-rxjava3:$room_version"
// optional - Guava support for Room, including Optional and ListenableFuture
implementation "androidx.room:room-guava:$room_version"
// optional - Test helpers
testImplementation "androidx.room:room-testing:$room_version"
// optional - Paging 3 Integration
implementation "androidx.room:room-paging:2.5.0-alpha01"
更新 1:
我的 TypeConverter (Converters.kt
) 如下所示:
class Converters {
@TypeConverter
fun uByteToInt(uByte: UByte): Int = uByte.toInt()
@TypeConverter
fun intToUByte(value: Int): UByte = value.toUByte()
}
和AppDatabase.kt
:
@Database(entities = [<...>::class], version = 1, exportSchema = false)
@TypeConverters(Converters::class)
abstract class AppDatabase : RoomDatabase() {
abstract fun sensorDao(): SensorDao
...
}
更新二:
可能值得注意的是 Class UInt8
是另一个实体中的嵌套 class,即:
@Entity()
data class simpleConfig(
@Embedded(prefix = "simplec_version_") val version: UInt8 =
UInt8("Field Version"),
...)
我认为这很可能是一个错误。
如果你有 UInt8,那么 Room 会生成 AppDatabase_Impl,table 将 UByte 识别为整数,例如
_db.execSQL("CREATE TABLE IF NOT EXISTS `UInt8` (`key` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `testvalue` INTEGER NOT NULL, `size` INTEGER NOT NULL, `readOnly` INTEGER NOT NULL)");
- 按照
createAllTables
方法
- 注意值已更改为测试值以确保重新生成它。
因此 Room 理解 UByte 等同于 INTEGER 列类型。
我认为,问题在于它正在处理 expects Int,因此默认的 getter 和 setter 不足。此外,TypeConverters 被忽略了,因为 Room 显然知道如何处理。
如果您改为使用:-
@Entity
data class UInt8(
@PrimaryKey(autoGenerate = true)
var key: Int,
var name: String = "uint8-test",
var testvalue: Int = 0,
var size: Int = 1,
var readOnly: Boolean = true
) {
constructor(key: Int, name: String, testvalue: UByte, size: Int, readOnly: Boolean): this(key,name, testvalue.toInt(),size,readOnly)
}
然后 Room 没有抱怨,但是 testvalue 在检索它时会是一个 Int。但是,您需要将 getter 覆盖为 return 从 Int 到 Ubyte。
- 见
但是,如果您创建了一个 class 来掩盖 Room 如何处理 UByte,并实施 suitable 类型的转换器,那么它们就会发挥作用。
所以如果你有例如。
data class MyUByte(
val value: UByte
)
并且有:-
@TypeConverter
fun myUByteToInt(myUByte: MyUByte): Int = myUByte.value.toInt()
@TypeConverter
fun intToMyUByte(value: Int): MyUByte = MyUByte(value.toUByte())
然后最后:-
@Entity
data class UInt8(
@PrimaryKey(autoGenerate = true)
var key: Int,
var name: String = "uint8-test",
var testvalue: MyUByte = MyUByte(0.toUByte()),
var size: Int = 1,
var readOnly: Boolean = true
)
那么 TypeConverters 就不会被忽略,编译就可以了。
我想在我的房间数据库中存储以下数据class。不知何故,我没有成功:
@Entity
data class UInt8(
@PrimaryKey(autoGenerate = true)
var key: Int,
var name: String = "uint8-test",
var value: UByte = 0.toUByte(),
var size: Int = 1,
var readOnly: Boolean = true
)
我的自动生成的构建文件总是出错:
C:<...>\UInt8.java:15: error: Cannot find getter for field.
private byte value;
Cannot find getter for field.
UShort
、UInt
和 ULong
相同。
但是,如果我用 Int
替换它,它似乎可以工作,但不是我想要的(它需要是一个 UByte。
build.grade
(来自developer.android.com):
def room_version = "2.4.2"
//implementation "androidx.room:room-runtime:$room_version"
//annotationProcessor "androidx.room:room-compiler:$room_version"
implementation "androidx.room:room-ktx:$room_version"
kapt "androidx.room:room-compiler:2.5.0-alpha01"
// kapt "org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.2.0"
// optional - RxJava2 support for Room
implementation "androidx.room:room-rxjava2:$room_version"
// optional - RxJava3 support for Room
implementation "androidx.room:room-rxjava3:$room_version"
// optional - Guava support for Room, including Optional and ListenableFuture
implementation "androidx.room:room-guava:$room_version"
// optional - Test helpers
testImplementation "androidx.room:room-testing:$room_version"
// optional - Paging 3 Integration
implementation "androidx.room:room-paging:2.5.0-alpha01"
更新 1:
我的 TypeConverter (Converters.kt
) 如下所示:
class Converters {
@TypeConverter
fun uByteToInt(uByte: UByte): Int = uByte.toInt()
@TypeConverter
fun intToUByte(value: Int): UByte = value.toUByte()
}
和AppDatabase.kt
:
@Database(entities = [<...>::class], version = 1, exportSchema = false)
@TypeConverters(Converters::class)
abstract class AppDatabase : RoomDatabase() {
abstract fun sensorDao(): SensorDao
...
}
更新二:
可能值得注意的是 Class UInt8
是另一个实体中的嵌套 class,即:
@Entity()
data class simpleConfig(
@Embedded(prefix = "simplec_version_") val version: UInt8 =
UInt8("Field Version"),
...)
我认为这很可能是一个错误。
如果你有 UInt8,那么 Room 会生成 AppDatabase_Impl,table 将 UByte 识别为整数,例如
_db.execSQL("CREATE TABLE IF NOT EXISTS `UInt8` (`key` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `testvalue` INTEGER NOT NULL, `size` INTEGER NOT NULL, `readOnly` INTEGER NOT NULL)");
- 按照
createAllTables
方法 - 注意值已更改为测试值以确保重新生成它。
因此 Room 理解 UByte 等同于 INTEGER 列类型。
我认为,问题在于它正在处理 expects Int,因此默认的 getter 和 setter 不足。此外,TypeConverters 被忽略了,因为 Room 显然知道如何处理。
如果您改为使用:-
@Entity
data class UInt8(
@PrimaryKey(autoGenerate = true)
var key: Int,
var name: String = "uint8-test",
var testvalue: Int = 0,
var size: Int = 1,
var readOnly: Boolean = true
) {
constructor(key: Int, name: String, testvalue: UByte, size: Int, readOnly: Boolean): this(key,name, testvalue.toInt(),size,readOnly)
}
然后 Room 没有抱怨,但是 testvalue 在检索它时会是一个 Int。但是,您需要将 getter 覆盖为 return 从 Int 到 Ubyte。
- 见
但是,如果您创建了一个 class 来掩盖 Room 如何处理 UByte,并实施 suitable 类型的转换器,那么它们就会发挥作用。
所以如果你有例如。
data class MyUByte(
val value: UByte
)
并且有:-
@TypeConverter
fun myUByteToInt(myUByte: MyUByte): Int = myUByte.value.toInt()
@TypeConverter
fun intToMyUByte(value: Int): MyUByte = MyUByte(value.toUByte())
然后最后:-
@Entity
data class UInt8(
@PrimaryKey(autoGenerate = true)
var key: Int,
var name: String = "uint8-test",
var testvalue: MyUByte = MyUByte(0.toUByte()),
var size: Int = 1,
var readOnly: Boolean = true
)
那么 TypeConverters 就不会被忽略,编译就可以了。