Oleg - Can you post the maven project with this test? My first thought is that this *should* work, but I can come up with some hypothetical cases where it might not work.
Thanks, Rick On Mon, Dec 9, 2013 at 12:02 PM, olyalikov <oleg.lyali...@alcatel-lucent.com > wrote: > Hello, > > In short: I have 2 entities - Person and Document, Person has a ManyToOne > link to the Document. I create Document in a separate thread/entity > manager, > close entity manager (and so document becomes detached) and then create > concurrently Person objects (in separate entity managers) setting document > field to the same detached Document object I created previously. > As a result some of the Person objects are persisted with null value in the > document field (in my tests 1 such Person object for ~2000 "good" Person > objects). > > Full story: > OpenJPA 2.2.2 is used + tomcat connection pool + no cache for simplicity. > Here are these entities (without setters and getters): > > @Entity > public class Person { > @Id @GeneratedValue > private String id; > > @ManyToOne > private Document document; > } > > @Entity > public class Document { > @Id @GeneratedValue > private String id; > } > > The code which creates Document: > final Document document = new Document(); > final EntityManager em = emf.createEntityManager(); > try { > final EntityTransaction tx = em.getTransaction(); > tx.begin(); > em.persist(document); > tx.commit(); > } finally { > em.close(); > } > > Then concurrently I create Person objects: > final EntityManager emCreation = emf.createEntityManager(); > try { > for (int j = 0; j < threadObjectCount; j++) { > final Person person = new Person(); > person.setDocument(document); > > final EntityTransaction tx = > emCreation.getTransaction(); > tx.begin(); > emCreation.persist(person); > tx.commit(); > > emCreation.refresh(person); > if (person.getDocument() == null) { > System.err.println("Person with null > Document found, id=" + > person.getId()); > } else { > succeded.incrementAndGet(); > } > } > } finally { > emCreation.close(); > } > > For some Person objects invocation of "person.getDocument()" returns null. > > Here is a SQL trace when Person is persisted with null Document: > 1687 openjpa-concurrent-creation-test TRACE [pool-2-thread-3] > openjpa.jdbc.SQL - <t 4934637, conn 22701741> executing prepstmnt 5327894 > INSERT INTO Person (id, DOCUMENT_ID) VALUES (?, ?) [params=(String) 1453, > (null) null] > And here is normal case: > 1687 openjpa-concurrent-creation-test TRACE [pool-2-thread-1] > openjpa.jdbc.SQL - <t 4358252, conn 30226657> executing prepstmnt 32228587 > INSERT INTO Person (id, DOCUMENT_ID) VALUES (?, ?) [params=(String) 1452, > (String) 1] > There is no more information from OpenJPA logs. > > Actually I have a maven project with this test and can send it, the test > consistently fails. > As a fix it's enough to "find" Document for each new EntityManager and use > it for Person objects. > > It seems that the Document is correctly published with regard to my code > and > other threads (it is not changed by my code after these threads start) but > it may be changed by OpenJPA during Person persist and in this case this > may > lead to the inproper view of Document object in different threads and > explain observed behaviour (perhaps). > > So I have several questions: > 1) Is Document object changed by OpenJPA when I persist Person object > (becomes managed or something)? > 2) Anyway is it possible to detect this situation by OpenJPA and react with > exception? Or maybe the Document object is not changed and there is some > other issue? > > Thanks, > Oleg > > > > -- > View this message in context: > http://openjpa.208410.n2.nabble.com/Incorrect-concurrent-persist-of-ManyToOne-field-tp7585744.html > Sent from the OpenJPA Users mailing list archive at Nabble.com. > -- *Rick Curtis*