我在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的。请帮助我。
所以,最后问题真的很微妙。由于我无法解释的原因,我正在做的项目有以下的gradle设置(app gradle)。
kapt "android.arch.persistence.room:compiler:2.2.5"
我把它换成了
kapt "androidx.room:room-compiler:2.2.5"
然后一切都好了。现在,插件生成的硬编码查询包含了JOIN,而且还能用......。