1

当我尝试保留新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()的应该写入数据库。

如果我替换persistmerge操作成功,但合并会导致休眠生成一个额外select的 theMunch和一个selectfor the Swipe,这是不必要的操作。然而,合并似乎没有将更新操作级联到Munch它只执行 2 个选择语句和 1 个插入。

回顾一下:Hibernate 似乎在不应该级联Persist操作时进行级联操作。一个解决方案是使用merge,但使用persist应该只导致1 insertwhere 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
}
4

1 回答 1

0

发生这种情况是因为您试图持久化不存在的对象,因此您应该首先使用 CascadeType.PERSIST 或持久化 SwipeIdKey 对象

于 2020-09-06T22:43:45.473 回答