gpt4 book ai didi

java - 如果 OneToMany 相关实体被分离,则级联时出现 PersistenceException

转载 作者:行者123 更新时间:2023-12-01 16:35:30 27 4
gpt4 key购买 nike

给出这个简单的例子(https://github.com/lelmarir/jpa-cascade-bug-test):

runInTransaction(em, () -> {
Parent p = em.find(Parent.class, id);
Child firstChild = p.getChilds().get(0);

em.detach(firstChild);
em.flush();
});

它将因以下错误而失败:

javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: com.example.Child
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:154)
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:181)
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:188)
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1356)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1339)
at com.example.App.lambda$1(App.java:47)
at com.example.App.runInTransaction(App.java:62)
at com.example.App.main(App.java:40)
Caused by: org.hibernate.PersistentObjectException: detached entity passed to persist: com.example.Child
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:120)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:113)
at org.hibernate.internal.SessionImpl.persistOnFlush(SessionImpl.java:755)
at org.hibernate.engine.spi.CascadingActions$8.cascade(CascadingActions.java:341)
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:492)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:416)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:218)
at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:525)
at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:456)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:419)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:218)
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:151)
at org.hibernate.event.internal.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:158)
at org.hibernate.event.internal.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:148)
at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:81)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:102)
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1352)
... 4 more

我应该将此报告为 Hibernate bug 还是预期行为?

最佳答案

is it an expected behaviour?

是的。

让我引用 JPA Specification 中的两段摘录适用于此处:

第一个:

The state of persistent entities is synchronized to the database at transaction commit. (...) If X is a managed entity, it is synchronized to the database. (...) For all entities Y referenced by a relationship from X, if the relationship to Y has been annotated with the cascade element value cascade=PERSIST or cascade=ALL, the persist operation is applied to Y

第二个:

The semantics of the persist operation, applied to an entity X are as follows: (...) If X is a detached object, the EntityExistsException may be thrown when the persist operation is invoked, or the EntityExistsException or another PersistenceException may be thrown at flush or commit time.

(强调我的)

我注意到很多人对这种行为感到困惑,实际上期望 JPA 刷新的行为就像在父实体上调用 merge() 一样。 但是,由于父实体已被管理,因此此时没有任何内容可以合并。

关于java - 如果 OneToMany 相关实体被分离,则级联时出现 PersistenceException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61957841/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com