]
Jakob Braeuchi commented on HHH-2763:
-------------------------------------
hi c. delaloye,
based on your testcase i found a solution that works without modification to the hibernate
code.
i mark all CollectionEntries created by traversing the relationships as processed:
public boolean onPreUpdate(PreUpdateEvent event) {
Object entity = event.getEntity();
System.out.println("-- Entering pre-update for " +
entity.getClass().getName());
Object[] oldValues = event.getOldState();
String[] properties = event.getPersister().getPropertyNames();
// Iterate through all fields of the updated object
for (int ii = 0; ii < properties.length; ii++)
{
if (oldValues != null && oldValues[ii] instanceof Collection)
{
Collection col = (Collection) oldValues[ii];
// Hibernate will initialize(load) the n:side of m:n collection,
// but this will lead to following error later:
// AssertionFailure:collection [n:side] was not processed
// by flush()
// get CollectionEntries before traversing the relationship
List entriesBeforeLoad = new ArrayList();
entriesBeforeLoad.addAll(event.getSource().getPersistenceContext()
.getCollectionEntries().values());
// traverse the relationship and do some stuff
for (Iterator iter = col.iterator(); iter.hasNext();)
{
Object element = (Object) iter.next();
System.out.println(element);
}
// get CollectionEntries after traversing the relationship
List entriesAfterLoad = new ArrayList();
entriesAfterLoad.addAll(event.getSource().getPersistenceContext()
.getCollectionEntries().values());
// keep CollectionEntries created by traversing and mark them as
processed.
entriesAfterLoad.removeAll(entriesBeforeLoad);
Iterator iter = entriesAfterLoad.iterator();
while (iter.hasNext())
{
CollectionEntry ce = (CollectionEntry) iter.next();
ce.setProcessed(true);
}
}
}
System.out.println("-- Exiting pre-update for " +
entity.getClass().getName());
return true;
}
i'm not sure whether this causes any side-effects in your code. just give it a try.
greetings
jakob braeuchi
(lazy) m:n relation + EventListener = AssertionFailure: collection
[n-side] was not processed by flush()
--------------------------------------------------------------------------------------------------------
Key: HHH-2763
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-2763
Project: Hibernate3
Issue Type: Bug
Components: core
Affects Versions: 3.2.4.sp1, 3.2.5
Environment: Windows-XP, Jboss 4.2.1GA, Hibernate 3.2.4SP1, EJB3
Reporter: S.Schnabl
Priority: Critical
Attachments: bidirectional_many-to-many.gif, cdel_analyse.txt,
HHH-2763_standalone_testcases.zip, one-to-many_with_many_side_having_collections.gif,
Testcase.zip
For more details see the attached testcase. I'm sorry, but in the short of time i
only got a testcase for jboss-server 4.2. Please deploy the server.ear from
/release-directory and then call the /src/client/TestCaseClient.java.
[Summarized]
It seems, that touching a lazy (Persistent-)Collection of at least a m:n relation inside
a Hibernate event-listener always raises this error:
org.hibernate.AssertionFailure: collection [n-side] was not processed by flush()
[Explanation]
I have two entities A. and B. Both having a m:n relation between each other. Furthermore
there is an PostUpdateListener, which iterates onUpdate of entitiy through all properties
of updated entity.
[Testcase]
Both entities are linked with eachother (m:n). If i now do a simple update of a property
of entity A --> MyPostUpdateListener will be called, which iterates through every
property of the updated entity. In case of this property was a collection (= lazy
PersistentCollection of m:n relation), hibernate initializes the collection for further
work. I can now run through all objects of the collection, but after all work is done in
listener, I get the following exception from postFlush:
Caused by: org.hibernate.AssertionFailure: collection
[com.qualitype.testcase.server.ejb.entity.EntityB.entitiesOfA] was not processed by
flush()
at org.hibernate.engine.CollectionEntry.postFlush(CollectionEntry.java:205)
at
org.hibernate.event.def.AbstractFlushingEventListener.postFlush(AbstractFlushingEventListener.java:333)
at
org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:28)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
at
org.hibernate.ejb.AbstractEntityManagerImpl$1.beforeCompletion(AbstractEntityManagerImpl.java:515)
... 29 more
Attention: EntityB.entitiesOfA is the other-side collection of the m:n relation of the
updated EntityA.
We are using hibernate-event listener system for auditing-purposes, so you should
understand that touching every (element in the) collection is necessary for
audit-purposes.
Seems for me like a serious bug. Need this fixed asap ...
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: