Getting "org.hibernate.HibernateException: Don't change the reference to a collection with cascade="all-delete-orphan": foo.pkg.Order.references"
Looking at the Hibernate source, this is thrown if the owning entity key changes or if the currentPersister is not the same as the loadedPersister.
My code loads an Order (implements DocumentHolder) in one request and stores it in a HTTP session variable. It adds a Document to it and tries to save it in the next request. I make no other changes to the Order object and I've verified that the key hasn't changed accidentally somehow.
Under what circumstances does the persister change? How can I verify that it is changing? How do I prevent it from changing?
Thanks,
Jesse
(P.S. I've change package names and omitted the portions of the logs that deal with other related objects for brevity and confidentiality.)
Hibernate version:
3.1 (JBoss 4.0.3SP1)
Mapping documents:
Code:
<hibernate-mapping schema="hl_workflow" package="foo.pkg">
<class name="Order" table="orders">
<id name="id" column="order_id" unsaved-value="null">
<generator class="native">
<param name="sequence">sq_orders</param>
</generator>
</id>
<version name="version"/>
<many-to-one name="account" column="account_id" cascade="persist,merge,save-update"/>
<set name="references" cascade="all-delete-orphan" lazy="true">
<key column="order_id" not-null="true"/>
<one-to-many class="OrderReference"/>
</set>
<!-- ... -->
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():Note: Using a Servlet Filter to initiate and commit/rollback a JTA UserTransaction. DocumentDao retrieves SessionFactory from JDNI and calls getCurrentSession()
Request 1:
Code:
public String viewDocuments() {
try {
OrderBean order = getOrder();
if(order != null) {
getSession().setSelectedDocumentHolder(order);
return "jbpm:task:" + getInstance().getId() + ":taskDocs.jsp";
} else {
FacesUtil.addMessage("There is no order associated with this task");
return "failure";
}
} catch(Throwable t) {
IncidentUtil.reportIncident("Error loading order for task " + getInstance(), t);
return "error";
}
}
Request 2:
Code:
public String upload() {
InputStream in = null;
try {
UploadedFile file = getUploadedFile();
if(file != null) {
DocumentDao docDao = new DocumentDao();
DocumentHolder holder = getInstance();
if(holder instanceof Order) {
_log.debug("order.id=" + ((Order)holder).getId());
}
in = file.getInputStream();
Document doc = new Document(file.getName(), file.getContentType(), in);
for(String keyWord: _keyWords) doc.addKeyWord(keyWord);
holder.addDocument(doc);
docDao.save(holder);
TransactionUtil.flush();
FacesUtil.addMessage("Document saved successfully");
_documentBeans = null;
return "success";
} else {
FacesUtil.addMessage("Please specify a file");
return "failure";
}
} catch(Throwable t) {
try { TransactionUtil.rollback(); } catch(Throwable t2) {}
IncidentUtil.reportIncident("Error saving document", t);
return "error";
} finally {
if(in != null) {
try { in.close(); } catch(Throwable t) {}
}
}
}
Full stack trace of any exception that occurs:Code:
14:41:27,869 ERROR Incident #1
Message: Error saving document
Exception: Root cause: org.hibernate.HibernateException: Don't change the reference to a collection with cascade="all-delete-orphan": foo.pkg.Order.references
at org.hibernate.engine.Collections.prepareCollectionForUpdate(Collections.java:209)
at org.hibernate.engine.Collections.processReachableCollection(Collections.java:168)
at org.hibernate.event.def.FlushVisitor.processCollection(FlushVisitor.java:37)
at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:101)
at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:61)
at org.hibernate.event.def.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:55)
at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:115)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:195)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:76)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:26)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:905)
at foo.pkg.TransactionUtil.flush(TransactionUtil.java:37)
at foo.pkg.FooBean.upload(DocumentHolderBean.java:76)
Name and version of the database you are using:Oracle 10g
The generated SQL (show_sql=true):N/A
Debug level Hibernate log excerpt:Code:
14:55:32,550 DEBUG [Cascade] processing cascade ACTION_SAVE_UPDATE for: foo.pkg.Order
14:55:32,557 DEBUG [Cascade] cascade ACTION_SAVE_UPDATE for collection: foo.pkg.Order.references
14:55:32,557 DEBUG [Cascade] done cascade ACTION_SAVE_UPDATE for collection: foo.pkg.Order.references
14:55:32,557 DEBUG [Cascade] deleting orphans for collection: foo.pkg.Order.references
14:55:32,557 DEBUG [Cascade] done deleting orphans for collection: foo.pkg.Order.references
14:55:32,558 DEBUG [Cascade] cascade ACTION_SAVE_UPDATE for collection: foo.pkg.Order.documents
14:55:32,559 DEBUG [CascadingAction] cascading to saveOrUpdate: foo.pkg.Document
14:55:32,559 DEBUG [AbstractSaveEventListener] persistent instance of: foo.pkg.Document
14:55:32,559 DEBUG [DefaultSaveOrUpdateEventListener] ignoring persistent instance
14:55:32,559 DEBUG [DefaultSaveOrUpdateEventListener] object already associated with session: [foo.pkg.Document#109]
14:55:32,559 DEBUG [Cascade] done cascade ACTION_SAVE_UPDATE for collection: foo.pkg.documents
14:55:32,559 DEBUG [Cascade] done processing cascade ACTION_SAVE_UPDATE for: foo.pkg.Order
14:55:32,559 DEBUG [Cascade] processing cascade ACTION_SAVE_UPDATE for: foo.pkg.Document
14:55:32,559 DEBUG [CascadingAction] cascading to saveOrUpdate: foo.pkg.DocumentContent
14:55:32,560 DEBUG [AbstractSaveEventListener] persistent instance of: foo.pkg.DocumentContent
14:55:32,560 DEBUG [DefaultSaveOrUpdateEventListener] ignoring persistent instance
14:55:32,560 DEBUG [DefaultSaveOrUpdateEventListener] object already associated with session: [foo.pkg.DocumentContent#109]
14:55:32,560 DEBUG [Cascade] done processing cascade ACTION_SAVE_UPDATE for: foo.pkg.Document
14:55:32,560 DEBUG [AbstractFlushingEventListener] dirty checking collections
14:55:32,560 DEBUG [CollectionEntry] Collection dirty: [foo.pkg.documents#1945]
14:55:32,560 DEBUG [AbstractFlushingEventListener] Flushing entities and processing referenced collections
14:55:32,564 DEBUG [DefaultFlushEntityEventListener] Updating entity: [foo.pkg.Order#1981]
14:55:32,564 DEBUG [Versioning] Incrementing: 0 to 1
14:55:32,565 DEBUG [Collections] Collection found: [foo.pkg.Order.references#1981], was: [foo.pkg.Order.references#1945] (uninitialized)