【发布时间】:2020-07-23 11:25:48
【问题描述】:
我有一个奇怪的问题。这是我的代码:
@Table(name = "rank")
@Entity
data class Rank(
@Id
private val id: String,
@Embedded
private var rankValue: RankValue,
@ElementCollection
@CollectionTable(
name="rank_change",
joinColumns = [JoinColumn(name = "rank_id")]
)
private val set: MutableSet<RankChange>
) {
fun calculateDifference(loseRank: Rank, rankPolicy: RankPolicy): Double {
return rankPolicy.calculateRankDifference(rankValue.value, loseRank.rankValue.value)
}
fun addChange(difference: Double, now: LocalDateTime, sparringId: String? = null) {
rankValue = rankValue.apply(difference)
set.add(RankChange(date = now, value = difference, sparringId = sparringId))
}
}
@Embeddable
data class RankChange(
@Column(name = "date")
private val date: LocalDateTime,
@Column(name = "value")
private val value: Double,
@Column(name = "sparring_id")
private val sparringId: String? = null
)
当我向MutableSet<RankChange> 添加元素时,休眠删除“rank_change”表并逐行插入。也许我应该实现 equals 和哈希码合同或使用 MutableList<T> 并添加 @OrderColumn 注释?但我真的不需要订单。
【问题讨论】:
-
这有什么奇怪的?
ElementCollection中的元素没有标识,因此 JPA 没有ElementCollection中“先前存在”元素的概念 -
好的,但是我可以改变这种行为吗?我的情况是我只想插入行。
-
解决方案非常简单:为对象赋予身份,即使它们成为实体并赋予它们
id -
好吧,但你不觉得这是人为的吗?
RankChange不是实体 - 它只是值对象。 -
身份与否,正是实体与值对象的区别。你本质上是在说:'这个对象不是一个实体,它不需要身份',同时,'JPA 需要识别这些对象来判断它们中的哪些先前存在,然后只插入新的,而不重写所有的行。你也不能一边吃蛋糕一边吃
标签: hibernate kotlin jpa collections hibernate-mapping