当我尝试保留新swipe
对象时,我遇到了以下异常:
javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: org.munch.database.models.bunch.Munch
这是我正在执行的代码:
databaseExecutor.executeAndRollbackOnFailure { entityManager ->
munch.swipes.forEach {
if (it.swipeIdKey.munchId != null) {
entityManager.persist(it)
} else if (it.updated) {
entityManager.merge(it)
}
}
entityManager.transaction.commit()
}
我还在下面粘贴了我的实体以供参考。调用时entityManager.persist(it)
,会抛出上述错误。出于某种原因,试图坚持OneToMany
实体的一面也是行不通的。我已经确保两个CascadeTypes
数组都是空的,所以根据我的理解,只有Swipe
我调用entityManager.persist()
的应该写入数据库。
如果我替换persist
为merge
操作成功,但合并会导致休眠生成一个额外select
的 theMunch
和一个select
for the Swipe
,这是不必要的操作。然而,合并似乎没有将更新操作级联到Munch
它只执行 2 个选择语句和 1 个插入。
回顾一下:Hibernate 似乎在不应该级联Persist
操作时进行级联操作。一个解决方案是使用merge
,但使用persist
应该只导致1 insert
where asmerge
结果2 selects + 1 insert
除了执行本地查询以插入/更新之外,我没有其他想法,但如果可能的话,我想避免这种情况。
这是我的实体:
Munch
@Entity
@TypeDefs(
TypeDef(
name = "list-array",
typeClass = ListArrayType::class
)
)
data class Munch(
@Column
val name: String,
@OneToMany(
fetch = FetchType.LAZY,
mappedBy = "munch",
)
val swipes: MutableList<Swipe> = mutableListOf(),
) {
@Id
@GenericGenerator(name = "generator", strategy = "uuid")
@GeneratedValue(generator = "generator")
lateinit var munchId: String
fun addSwipe(swipe: Swipe) {
swipes.add(swipe)
swipe.munch = this
}
}
Swipe
@Entity
data class Swipe(
@EmbeddedId
val swipeIdKey: SwipeIdKey,
@Column(nullable = true)
val liked: Boolean,
) : Serializable {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "munchId")
@MapsId("munchId")
lateinit var munch: Munch
@Transient
var updated = false
SwipeIdKey
@Embeddable
class SwipeIdKey : Serializable {
@Column(nullable = false)
lateinit var restaurantId: String
@Column(nullable = true)
lateinit var userId: String
@Column(nullable = true)
var munchId: String? = null
}