[hibernate-issues] [Hibernate-JIRA] Commented: (HHH-2269) Many-to-one cascade fails with TransientObjectException if the inverse collection is marked CascadeType.DELETE_ORPHAN

Gail Badner (JIRA) noreply at atlassian.com
Mon Oct 8 19:38:39 EDT 2007


    [ http://opensource.atlassian.com/projects/hibernate/browse/HHH-2269?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_28385 ] 

Gail Badner commented on HHH-2269:
----------------------------------

I've committed tests for bidirectional one-to-many associations with both sides cascading based on Edward Costello test case. One test reproduces this issue by failing with TransientObjectException if the inverse collection is marked CascadeType.DELETE_ORPHAN. This test was added as a "FailureExpected" test.

> Many-to-one cascade fails with TransientObjectException if the inverse collection is marked CascadeType.DELETE_ORPHAN
> ---------------------------------------------------------------------------------------------------------------------
>
>                 Key: HHH-2269
>                 URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-2269
>             Project: Hibernate3
>          Issue Type: Bug
>          Components: core
>    Affects Versions: 3.2.0.cr2, 3.2.1
>         Environment: Using hibernate annotations.
>            Reporter: Edward Costello
>         Attachments: new-testcase.tgz, TestBidirectionalCascade.java
>
>
> When both a many-to-one (child) and it's inverse one-to-many collection (on parent) are cascading. Attempting to save a child directly and cascade the save to the parent throws a TransientObjectException if the parent's collection is mapped CascadeType.DELETE_ORPHAN. For Example, with the classes below:
> 	@Entity
> 	public class Parent {
> 		@OneToMany(mappedBy = "parent")
> 		@Cascade(value = {CascadeType.ALL, CascadeType.DELETE_ORPHAN})
> 		Set<DeleteOrphanChild> deleteOrphanChildren;
> 	}
> 	@Entity
> 	public class DeleteOrphanChild {
> 		@ManyToOne
> 		@Cascade(value = CascadeType.ALL)
> 		Parent parent;
> 	}
> Calling session.save() with an instance of the parent will cascade the save to the child as expected. However, calling save on an instance of the child will throw the TransientObjectException below while attempting to cascade the save to the parent.
> org.hibernate.TransientObjectException: cascade.test.TestBidirectionalCascade$DeleteOrphanChild
> 	at org.hibernate.engine.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:216)
> 	at org.hibernate.collection.AbstractPersistentCollection.getOrphans(AbstractPersistentCollection.java:889)
> 	at org.hibernate.collection.PersistentSet.getOrphans(PersistentSet.java:51)
> 	at org.hibernate.engine.CollectionEntry.getOrphans(CollectionEntry.java:350)
> 	at org.hibernate.engine.Cascade.deleteOrphans(Cascade.java:336)
> 	at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:318)
> 	at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:185)
> 	at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:160)
> 	at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:108)
> 	at org.hibernate.engine.Cascade.cascade(Cascade.java:248)
> 	at org.hibernate.event.def.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:437)
> 	at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:326)
> 	at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:180)
> 	at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:108)
> 	at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:186)
> 	at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:175)
> 	at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:98)
> 	at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
> 	at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:509)
> 	at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:501)
> 	at org.hibernate.engine.CascadingAction$1.cascade(CascadingAction.java:134)
> 	at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:213)
> 	at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:157)
> 	at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:108)
> 	at org.hibernate.engine.Cascade.cascade(Cascade.java:248)
> 	at org.hibernate.event.def.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:412)
> 	at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:261)
> 	at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:180)
> 	at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:108)
> 	at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:186)
> 	at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:33)
> 	at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:175)
> 	at org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:27)
> 	at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
> 	at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:537)
> 	at org.hibernate.impl.SessionImpl.save(SessionImpl.java:525)
> 	at org.hibernate.impl.SessionImpl.save(SessionImpl.java:521)
> If the DELETE_ORPHAN cascade is removed the save works fine. The attached test case runs against an in memory HSQLDB database. It contains 4 tests, the second test (testSaveChildDeleteOrphan) fails showing the above exception. The other three pass showing that cascading from the parent works and that cascading in both directions remove if the DELETE_ORPHAN cascade is removed.
> We've only tested this with annotations, we haven't tried to reproduce it using hibernate mapping files.

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        



More information about the hibernate-issues mailing list