Room数据库中的多对多关系。Kotlin Junction类忽略了

问题描述 投票:0回答:1

我在Room ver.2.5中有以下Kotlin实体。2.2.5.

实体

@Entity(tableName = "ITEM",
    indices = [Index(value = ["id"], unique = true), Index(value = ["code"], unique = true), Index(value = ["status"], unique = false)]
)
data class Item (
    @PrimaryKey @ColumnInfo(name = "id") override val id: UUID = UUID.randomUUID(),
    @ColumnInfo(name = "code") @NotNull val code: String,
    @ColumnInfo(name = "valid") val valid: Boolean = true,
    @ColumnInfo(name = "value") val value: Double?,
    @ColumnInfo(name = "price") val price: Double?,
    @ColumnInfo(name = "default_description") val defaultDescription: String?,
    @ColumnInfo(name = "description") val description: String?
)

子实体

@Entity(tableName = "LOCATION",
    indices = [Index(value = ["id"], unique = true), Index(value = ["code"], unique = true)]
)
data class Location (
    @ColumnInfo(name = "id") @PrimaryKey override val id: UUID = UUID.randomUUID(),
    @ColumnInfo(name = "code") val code: String,
    @ColumnInfo(name = "latitude") val latitude: Double?,
    @ColumnInfo(name = "longitude") val longitude: Double?,
    @ColumnInfo(name = "default_description") val defaultDescription: String?
)

联结实体

@Entity(
    tableName = "ITEM_LOCATION_L",
    primaryKeys = [
        "item_id", "location_id"
    ],
    foreignKeys = [
        ForeignKey(entity = Item::class, parentColumns = ["id"], childColumns = ["item_id"]),
        ForeignKey(entity = Location::class, parentColumns = ["id"], childColumns = ["location_id"])
    ],
    indices = [
        Index("id"),
        Index("item_id"),
        Index("location_id")])
data class ItemLocationLink (
    @ColumnInfo(name = "id") override val id: UUID = UUID.randomUUID(),
    @ColumnInfo(name = "item_id") val itemId: UUID, /** Item ID - parent entity */
    @ColumnInfo(name = "location_id") val locationId: UUID, /** Location ID - child entity */
    @ColumnInfo(name = "quantity") val quantity: Double /** Quantity of the item in the referenced location */
)

结果类

class ItemLocationRelation {
    @Embedded
    lateinit var item: Item
    @Relation(
        parentColumn = "id",
        entityColumn = "id",
        associateBy = Junction(value = ItemLocationLink::class, parentColumn = "item_id", entityColumn = "location_id")
    ) lateinit var locations: List<Location>
}

DAO INTERFACE

@Dao
interface ItemLocationLinkDao {

   @Transaction
    @Query("SELECT * FROM ITEM WHERE id = :itemId")
    fun getLocationsForItem(itemId: UUID): List<ItemLocationRelation>
}

数据库类型转换器

class DBTypesConverter {

    @TypeConverter
    fun fromUUID(uid: UUID?): String? {

        if (uid != null)
            return uid.toString()
        return null
    }

    @TypeConverter
    fun toUUID(str: String?): UUID? {

        if (str != null) {
            return UUID.fromString(str)
        }
        return null
    }

    @TypeConverter
    fun fromDate(d: Date?): Long? {

        return d?.time
    }

    @TypeConverter
    fun toDate(l: Long?): Date? {

        return if (l != null) Date(l) else null
    }
}

当我打电话 getLocationsForItem 我得到的回报是一个 项目位置关系 有一个有效的Item,但没有子对象。我检查了生成的代码,没有Junction类的迹象。生成的代码表现得好像不是一个多对多关系,Junction类完全被忽略了,我甚至可以在关系的@Junction属性中指定一个假的类,结果也会完全一样,没有错误。

如果我在DAO类中添加一个函数,返回以下查询的结果。

select * from item 
inner join item_location_l as link on link.item_id = item.id
inner join LOCATION as l on link.location_id = l.id
where item.id = '99a3a64f-b0e6-e911-806a-68ecc5bcbe06'

我得到了2行预期的结果 所以SQLite数据库是OK的。请帮助我。

android kotlin foreign-keys android-room
1个回答
1
投票

所以,最后问题真的很微妙。由于我无法解释的原因,我正在做的项目有以下的gradle设置(app gradle)。

kapt "android.arch.persistence.room:compiler:2.2.5"

我把它换成了

kapt "androidx.room:room-compiler:2.2.5"

然后一切都好了。现在,插件生成的硬编码查询包含了JOIN,而且还能用......。

© www.soinside.com 2019 - 2024. All rights reserved.