无法在Android(Kotlin)上使用ObjectBox保存相同的数据

时间:2018-08-14 08:59:36

标签: android kotlin objectbox

我正在使用ObjectBox保存数据。当我使用ToMany保存相同的数据时,它只会保存第一个。

  • ObjectBox(version:2.0.0)
  • Android(目标SDK版本:27)
  • 科特琳(版本:1.2.60)

这是我的代码。

@Entity
data class Order(@Id var id: Long = 0,
                 val createTime: Long = 0,
                 val total: Int = 0) {

    @Backlink(to = "order")
    lateinit var details: ToMany<OrderDetail>
}

@Entity
data class OrderDetail(@Id var id: Long = 0,
                       val productName: String = "",
                       val productSpecName: String = "",
                       val productSpecPrice: Int = 0,
                       val quantity: Int = 0,
                       val subtotal: Int = 0) {

    lateinit var order: ToOne<Order>
}

测试

@Test
    fun orderDetailTest() {

        val orderBox = store.boxFor(Order::class.java)

        // 儲存兩個內容相同的資料
        val order = Order().apply {
            this.details.add(OrderDetail(productSpecName = "ABC"))
            this.details.add(OrderDetail(productSpecName = "ABC"))
        }

        val orderId = orderBox.put(order)

        val result = orderBox.get(orderId)

        assert(result.details.size == 2)
    }

result.details的大小为1。

我可以使用ToMany保存多个相同的数据吗?我该如何解决?

感谢您的回答。

2 个答案:

答案 0 :(得分:1)

Kotlin data classeshashCode()提供了一个自定义实现。 ToMany使用HashMap来跟踪要添加或删除的实体。我想您可以看到问题所在:

基于Kotlin数据类的实现,如果两个数据类具有相同的属性,则它们的哈希码匹配。现在,根据此示例,根据其OrderDetail使用两个相同的hashCode()数据类:

val order = Order().apply {
    this.details.add(OrderDetail(productSpecName = "ABC"))
    this.details.add(OrderDetail(productSpecName = "ABC"))
}

两个实体将添加到ToMany列表中。但是,内部更改跟踪机制假定第二个实体替换了第一个实体,因为HashMap认为它们是相同的。因此,只添加了一个。

使OrderDetail成为常规类(删除data关键字)会删除自定义hashCode()实现,一切都会按预期进行。

我相信在Kotlin中,两个共享相同属性的数据类被视为“相同”,因此这种行为是可以预期的。尽管我同意这是不直观的。不确定我们应该在这里做什么。

Related GitHub Issue

答案 1 :(得分:0)

您需要指定OrderDetail id,否则默认情况下始终为0,并将覆盖之前的订单明细。

val orderDetail = OrderDetail(id = 1, productSpecName = "ABC")
orderDetail.order = order
this.details.add(orderDetail)
val orderDetail2 = OrderDetail(id = 2, productSpecName = "ABC")
orderDetail2.order = order
this.details.add(orderDetail2)