房间递归关系解决方法

时间:2019-10-17 16:32:38

标签: java android sqlite kotlin android-room

问题:我正在尝试与房间建立递归关系。

我的代码

data class CachedServiceItemWithMediaItem(

    @Embedded
    val cachedServiceItem: CachedServiceItem? = null,
    @Relation(parentColumn = "id", entityColumn = "parentId", entity = CachedServiceItem::class)
    val cachedServiceItems: List<CachedServiceItemWithMediaItem>? = null

)

但这会引发e:[kapt]发生异常:java.lang.StackOverflowError。

如果我只有一个与CachedServiceItems相关的CachedServiceItem却没有其他子项,则它起作用:

data class CachedServiceItemWithMediaItem(

    @Embedded
    val cachedServiceItem: CachedServiceItem? = null,
    @Relation(parentColumn = "id", entityColumn = "parentId", entity = CachedServiceItem::class)
    val cachedServiceItems: List<CachedServiceItem>? = null

)

我尝试过的操作根据此答案https://stackoverflow.com/a/52329405/6317480,但是没有空间是可能的:

  

请注意,@ Relation批注只能在Pojo类中使用,   实体类不能有关系。这是要避免的设计决策   实体设置中常见的陷阱。您可以在   主要会议室文件。加载数据时,您只需解决   通过创建扩展实体的Pojo类来限制这种限制。

我不理解解决方法应该如何工作?

还有其他解决方法吗?

1 个答案:

答案 0 :(得分:0)

  

但这会引发e:[kapt]发生异常:java.lang.StackOverflowError。

一个CachedSericeItemsWithMedia中将有多少个CachedServiceItemsWithMedia? (修辞)。答案=无限,除非有限制因素。因此,堆栈溢出。

  

但是这也不起作用。

不确定要执行的操作到底是什么,但请考虑起作用的内容:-

@Entity
class CachedServiceItem {
    @PrimaryKey
    var id: String = ""
    var parentId: String? = null
    var imageBundleName: String = ""
    var position: Int = 0
    var text: String = ""
    var typeId: Int = 0
    var value: String = ""
}

与:-

data class CachedServiceItemWithMediaItem(

    @Embedded
    val cachedServiceItem: CachedServiceItem? = null,
    @Relation(parentColumn = "id", entityColumn = "parentId", entity = CachedServiceItem::class)
    val cachedServiceItems: List<CachedServiceItem>? = null
)

和一个Dao:-

@Dao
interface CachedServiceItemDao {

    @Insert(onConflict = OnConflictStrategy.IGNORE)
    fun insertCachedServiceItem(cachedServiceItem: CachedServiceItem) : Long

    @Query("SELECT * FROM cachedserviceitem")
    fun myList(): List<CachedServiceItemWithMediaItem>
}

最后:-

    val cachedServiceItemDao = db.cachedServiceItemDao()

    val csi = CachedServiceItem()
    csi.id = "csi1"
    csi.imageBundleName = "x"
    csi.position = 10
    csi.typeId = 100
    csi.text = "blah"
    csi.value = "myvalue"
    csi.parentId = null
    cachedServiceItemDao.insertCachedServiceItem(csi)

    val csi2 = CachedServiceItem()
    csi2.id = "csi2"
    csi2.position = 50
    csi2.typeId = 99
    csi2.text = "not blah"
    csi2.value = "another value"
    csi2.parentId = "csi1"
    cachedServiceItemDao.insertCachedServiceItem(csi2)

    var csi3 = CachedServiceItem()
    csi3.id = "csi3"
    csi.parentId = "csi3"
    cachedServiceItemDao.insertCachedServiceItem(csi3)

    csi3.id = "csi4"
    csi3.parentId = "csi3"
    cachedServiceItemDao.insertCachedServiceItem(csi3)

    csi3.id = "csi5"
    csi3.parentId = null
    cachedServiceItemDao.insertCachedServiceItem(csi3)

    var cachedServiceItemWithMediaList: List<CachedServiceItemWithMediaItem> = cachedServiceItemDao.myList()
    for(csiwml: CachedServiceItemWithMediaItem in cachedServiceItemWithMediaList) {
        Log.d("CSIWMLINFO",
            "CORE EMBEDDED CSI ID = " + csiwml.cachedServiceItem?.id + ". CSI's In List = " + csiwml.cachedServiceItems!!.size + ". They are :-"

            )
        for (csi: CachedServiceItem in csiwml.cachedServiceItems!!) {
            Log.d("CSIWMLINFO", "Listed CSI ID is" + csi.id)
        }
    }

则结果输出为:-

2019-10-18 14:21:21.583 D/CSIWMLINFO: CORE EMBEDDED CSI ID = csi1. CSI's In List = 1. They are :-
2019-10-18 14:21:21.584 D/CSIWMLINFO: Listed CSI ID iscsi2
2019-10-18 14:21:21.584 D/CSIWMLINFO: CORE EMBEDDED CSI ID = csi2. CSI's In List = 0. They are :-
2019-10-18 14:21:21.584 D/CSIWMLINFO: CORE EMBEDDED CSI ID = csi3. CSI's In List = 1. They are :-
2019-10-18 14:21:21.584 D/CSIWMLINFO: Listed CSI ID iscsi4
2019-10-18 14:21:21.584 D/CSIWMLINFO: CORE EMBEDDED CSI ID = csi4. CSI's In List = 0. They are :-
2019-10-18 14:21:21.584 D/CSIWMLINFO: CORE EMBEDDED CSI ID = csi5. CSI's In List = 0. They are :-

唯一似乎不起作用的是,当行引用自身时,在这种情况下,根据具有csi3父级的csi3,它会忽略自身的添加。