无法使用带 Android 的 ObjectBox 保存相同的数据 (Kotlin)
Can't save same data using ObjectBox with Android (Kotlin)
我正在使用 ObjectBox 来保存数据。当我用 ToMany 保存相同的数据时,它只保存第一个。
- 对象框(版本:2.0.0)
- Android(目标 sdk version: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 保存多个相同的数据吗?我该如何解决?
感谢您的回答。
您需要指定 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)
Kotlin data classes 为 hashCode()
提供自定义实现等。 ToMany
使用 HashMap
来跟踪要添加或删除的实体。我想你可以看到这是怎么回事:
基于 Kotlin 数据 class 实现,如果两个数据 class 具有相同的属性,则它们的哈希码匹配。现在给出这个例子,根据它们的 hashCode()
:
,有两个相同的 OrderDetail
数据 classes
val order = Order().apply {
this.details.add(OrderDetail(productSpecName = "ABC"))
this.details.add(OrderDetail(productSpecName = "ABC"))
}
两个实体将添加到 ToMany
列表中。但是,内部更改跟踪机制假定第二个实体替换第一个实体,因为 HashMap
认为它们是相同的。因此只添加了一个。
使 OrderDetail
成为常规 class(删除 data
关键字) 删除自定义 hashCode()
实现,一切正常不出所料。
我相信在 Kotlin 中,共享相同属性的两个数据 classes 被认为是 "the same",所以这种行为是意料之中的。虽然我同意这是不直观的。不确定我们应该在这里做什么。
我正在使用 ObjectBox 来保存数据。当我用 ToMany 保存相同的数据时,它只保存第一个。
- 对象框(版本:2.0.0)
- Android(目标 sdk version: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 保存多个相同的数据吗?我该如何解决?
感谢您的回答。
您需要指定 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)
Kotlin data classes 为 hashCode()
提供自定义实现等。 ToMany
使用 HashMap
来跟踪要添加或删除的实体。我想你可以看到这是怎么回事:
基于 Kotlin 数据 class 实现,如果两个数据 class 具有相同的属性,则它们的哈希码匹配。现在给出这个例子,根据它们的 hashCode()
:
OrderDetail
数据 classes
val order = Order().apply {
this.details.add(OrderDetail(productSpecName = "ABC"))
this.details.add(OrderDetail(productSpecName = "ABC"))
}
两个实体将添加到 ToMany
列表中。但是,内部更改跟踪机制假定第二个实体替换第一个实体,因为 HashMap
认为它们是相同的。因此只添加了一个。
使 OrderDetail
成为常规 class(删除 data
关键字) 删除自定义 hashCode()
实现,一切正常不出所料。
我相信在 Kotlin 中,共享相同属性的两个数据 classes 被认为是 "the same",所以这种行为是意料之中的。虽然我同意这是不直观的。不确定我们应该在这里做什么。