【发布时间】:2026-01-25 09:35:02
【问题描述】:
我正在开发一个 Kotlin 多平台项目,但遇到了保存数据库实体对象的问题。当我调用我的 sqldelight dao 类的插入方法时抛出异常
kotlinx.serialization.SerializationException: Serializer for class 'UnitEntity' is not found.
Mark the class as @Serializable or provide the serializer explicitly.
at kotlinx.serialization.internal.Platform_commonKt.serializerNotRegistered(Platform.common.kt:91)
at kotlinx.serialization.internal.PlatformKt.platformSpecificSerializerNotRegistered(Platform.kt:29)
at kotlinx.serialization.SerializersKt__SerializersKt.serializer(Serializers.kt:59)
at kotlinx.serialization.SerializersKt.serializer(Unknown Source:1)
.....
那个例子类就是生成的实体类
import com.example.package.core.entity.UnitEntity;
import com.example.package.core.entity.ResourceTypeEntity;
CREATE TABLE IF NOT EXISTS `ResourceEntity` (
`id` TEXT NOT NULL,
`name` TEXT NOT NULL,
`unitEntity` TEXT AS UnitEntity NOT NULL,
`type` TEXT AS ResourceTypeEntity NOT NULL,
PRIMARY KEY(`id`));
CREATE TABLE IF NOT EXISTS `ResourceTypeEntity` (
`typeId` TEXT NOT NULL,
`typeName` TEXT NOT NULL,
PRIMARY KEY(`typeId`)
);
CREATE TABLE IF NOT EXISTS `UnitEntity` (`unitId` TEXT NOT NULL, `unitName` TEXT NOT NULL, PRIMARY KEY(`unitId`));
save:
INSERT OR REPLACE INTO ResourceEntity
VALUES ?;
这里是 DAO 类:
class ResourcesDaoImpl(private val dao: Resources_daoQueries) : ResourcesDao {
override suspend fun save(resources: List<ResourceEntity>) {
resources.forEach {
dao.save(it)
}
}
}
当我尝试调用该保存方法时,它崩溃并说将该类标记为@Serializable,但我不明白它为什么这么说,因为它是一个生成的类,我无法修改这些类。
这是我如何尝试保存这些实体的 sn-p
val mappedData = itemsDto.map {
ResourceEntity(
id = it._id,
name = it.name,
type = ResourceTypeEntity(typeId = it.type._id, typeName = it.type.name),
unitEntity = UnitEntity(unitId = it.unit._id, unitName = it.unit.unit)
)
}
resourcesDao.save(mappedData)
图书馆:
val coroutinesVersion = "1.3.9-native-mt"
val ktor_version = "1.4.2"
val serializationVersion = "1.0.0-RC"
val koin_version = "3.0.0-alpha-4"
val sqlDelight = "1.4.4"
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:$serializationVersion")
implementation("com.squareup.sqldelight:runtime:$sqlDelight")
// SqlDelight extension
implementation("com.squareup.sqldelight:coroutines-extensions:$sqlDelight")
这里是实际的entities 和由SqlDelight 生成的保存方法
data class ResourceTypeEntity(
val typeId: String,
val typeName: String
) {
override fun toString(): String = """
|ResourceTypeEntity [
| typeId: $typeId
| typeName: $typeName
|]
""".trimMargin()
}
RecourceEntity.class
import com.squareup.sqldelight.ColumnAdapter
data class ResourceEntity(
val id: String,
val name: String,
val unitEntity: UnitEntity,
val type: ResourceTypeEntity
) {
override fun toString(): String = """
|ResourceEntity [
| id: $id
| name: $name
| unitEntity: $unitEntity
| type: $type
|]
""".trimMargin()
class Adapter(
val unitEntityAdapter: ColumnAdapter<UnitEntity, String>,
val typeAdapter: ColumnAdapter<ResourceTypeEntity, String>
)
}
UnitEntity.class
data class UnitEntity(
val unitId: String,
val unitName: String
) {
override fun toString(): String = """
|UnitEntity [
| unitId: $unitId
| unitName: $unitName
|]
""".trimMargin()
}
保存方法
override fun save(ResourceEntity: ResourceEntity) {
driver.execute(-1658323214, """
|INSERT OR REPLACE INTO ResourceEntity
|VALUES (?, ?, ?, ?)
""".trimMargin(), 7) {
bindString(1, ResourceEntity.id)
bindString(2, ResourceEntity.name)
bindString(3,
database.ResourceEntityAdapter.unitEntityAdapter.encode(ResourceEntity.unitEntity))
bindString(4, database.ResourceEntityAdapter.typeAdapter.encode(ResourceEntity.type))
}
notifyQueries(-1658323214, {database.resources_daoQueries.getResources +
database.resources_daoQueries.getResourceByManufacturerId})
}
【问题讨论】:
-
你的
@Serializer类上面有@Serializer注释吗? -
我无法添加注释,因为该类是由 SqlDelight 自动生成的
标签: android kotlin-multiplatform kotlinx.serialization sqldelight