openjpa-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Rick Curtis <curti...@gmail.com>
Subject Re: Incorrect concurrent persist of ManyToOne field
Date Mon, 09 Dec 2013 19:23:12 GMT
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.lyalikov@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*

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message