Hibernate Books

All times are UTC - 5 hours [ DST ]



Post new topic Reply to topic  [ 2 posts ] 
Author Message
 Post subject: Multi threads : flush during cascade is dangerous, etc...
PostPosted: Mon Mar 19, 2012 6:38 am 
Newbie

Joined: Mon Mar 19, 2012 6:02 am
Posts: 2
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#p2418145

However, 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.


Top
 Profile  
 
 Post subject: Re: Multi threads : flush during cascade is dangerous, etc...
PostPosted: Tue Mar 20, 2012 9:17 am 
Newbie

Joined: Mon Mar 19, 2012 6:02 am
Posts: 2
I've finally tracked it down. The entity manager in thread 1 was in a specific way used by thread 2.

Thread local session pattern is now my friend, and my bug is resolved.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 2 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.