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()
をdbに書き込む必要があることを理解しています。
操作で置き換えるpersist
とmerge
成功しますが、マージにより、休止状態が追加select
の と のMunch
を生成しますがselect
、Swipe
これは不要な操作です。Munch
ただし、マージは、更新操作を2 つの select ステートメントと 1 つの挿入のみにカスケードしているようには見えません。
要約すると、Hibernate はPersist
操作をカスケードしてはならない場合にカスケードしているようです。解決策はmerge
代わりに使用するpersist
ことですが、使用する1 insert
と、merge
結果として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
}