Hi all,
Hibernate version : 3.6.10, JPA2
First of all, my problem really looks like this one (that remained unanswered) :
https://forum.hibernate.org/viewtopic.php?f=1&t=999664&p=2418145&hilit=collection+was+processed+twice+by+flush#p2418145However, my situation is simpler.
My entities look like this :
A 1---->* B 1---->* C
And also B 1---->* D
(A points to multiple B, which points to multiple C, and multiple D)
Additionally, B has a boolean property. Lets call it 'dirty'. When a B is instanciated, its collection of D is initialized to a new HashSet.
All relations are bi-directionnal with at least cascade set to { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH }. Please tell me if it looks important for my problem. I can say more.
All my entities have a field annotated with @Version, and another one annotated with @Id.
From thread 1, I do this :
Code:
entityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
A a = new A();
entityManager.persist(a);
B b = new B();
entityManager.persist(b);
b.setA(a);
entityManager.getTransaction().commit();
From thread 2, I am polling the database state :
Code:
// Given the same entityManagerFactory than in thread 1 (is this the problem ?)
EntityManager entityManager = entityManagerFactory.createEntityManager();
// Query being a string in SQL checking the property 'dirty' on B
List<B> result = entityManager.createQuery(query).getResultList();
for (B b : result) {
// detail of businessMethodCall() below...
Collection<C> cs = b.businessMethodCall();
entityManager.getTransaction().begin();
for (C c : cs) {
entityManager.persist(c);
}
entityManager.getTransaction().commit();
}
entityManager.clear();
entityManager.close();
And where businessMethodCall update the property 'dirty' of b, clears the list of c held by b, check a rule that do things like this :
Code:
b.setDirty(false);
b.getCs().clear();
for(D d : this.getD()) {
// Always true, of course for the example
if(true) {
C c = new C();
this.getCs().add(c);
}
And I am getting different things like those ones (not always the same, intermittent...) :
Code:
Caused by: javax.persistence.PersistenceException: org.hibernate.HibernateException: Flush during cascade is dangerous
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1389)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1317)
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:81)
... 26 more
Caused by: org.hibernate.HibernateException: Flush during cascade is dangerous
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1212)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:383)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:133)
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:76)
... 26 more
Code:
Caused by: org.hibernate.AssertionFailure: collection [C] was not processed by flush()
at org.hibernate.engine.CollectionEntry.postFlush(CollectionEntry.java:228)
at org.hibernate.event.def.AbstractFlushingEventListener.postFlush(AbstractFlushingEventListener.java:352)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:52)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:383)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:133)
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:76)
... 26 more
This is in a test case, and I hope that it does not come from this (I am pretty sure that it does not). I must be doing something wrong with threads, entity managers... But what ?
Please help.
Thanks in advance.