|
Let's assume we have the following entities:
@Entity
@Table(name = "mouth")
public static class Mouth {
@Id
@GeneratedValue
public Integer id;
@OneToMany(mappedBy = "mouth", cascade = {CascadeType.ALL} )
public Collection<Tooth> teeth;
}
@Entity
@Table(name = "tooth")
public static class Tooth {
@Id
@GeneratedValue
public Integer id;
public String type;
@ManyToOne
public Mouth mouth;
}
Let's persist a tooth and a mouth containing an empty collection of teeth:
EntityManager em = getOrCreateEntityManager();
em.getTransaction().begin();
Tooth tooth = new Tooth();
Mouth mouth = new Mouth();
em.persist( mouth );
em.persist(tooth);
mouth.teeth = new ArrayList<Tooth>();
em.getTransaction().commit();
em.close();
At this point, tooth is detached. Now in a new session, let's retrieve the mooth instance from database and add tooth its teeth collection:
em = getOrCreateEntityManager();
em.getTransaction().begin();
Mouth mouth1 = em.find(Mouth.class, mouth.id);
mouth1.teeth.add(tooth);
tooth.mouth = mouth1;
At this point, if we call em.flush the following exception is thrown:
org.hibernate.PersistentObjectException: detached entity passed to persist: org.hibernate.jpa.test.cascade.DetachAndContainsTest$Tooth
javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: org.hibernate.jpa.test.cascade.DetachAndContainsTest$Tooth
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1692)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1602)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1608)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:1303)
at org.hibernate.jpa.test.cascade.DetachAndContainsTest.testDetachCollectionElementAndFlush(DetachAndContainsTest.java:80)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.hibernate.testing.junit4.ExtendedFrameworkMethod.invokeExplosively(ExtendedFrameworkMethod.java:45)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.internal.runners.statements.FailOnTimeout$StatementThread.run(FailOnTimeout.java:74)
Caused by: org.hibernate.PersistentObjectException: detached entity passed to persist: org.hibernate.jpa.test.cascade.DetachAndContainsTest$Tooth
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:124)
at org.hibernate.internal.SessionImpl.firePersistOnFlush(SessionImpl.java:801)
at org.hibernate.internal.SessionImpl.persistOnFlush(SessionImpl.java:794)
at org.hibernate.engine.spi.CascadingActions$8.cascade(CascadingActions.java:340)
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:379)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:304)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:146)
at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:412)
at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:344)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:307)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:146)
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:95)
at org.hibernate.event.internal.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:150)
at org.hibernate.event.internal.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:141)
at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:74)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:38)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1224)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:1300)
... 13 more
|