This discussion is archived
4 Replies Latest reply: Jun 4, 2013 6:48 AM by 635546 RSS

find: Problems with keeping managed associated entities (1-1 associations)

635546 Newbie
Currently Being Moderated
Hello,

Let us imagine we have this association:

FCalendar <-------->Competition

This association is bidirectional and one-to-one.

Furthermore, let us imagine that the database already contains a Competition with id "Comp111".

I have created:

Competition comp = new Competition("Comp111");
....
FCalendar cal =new FCalendar("Cal111"); //"Cal111" is the identifier of this calendar object.
cal.setCompetition(comp);
comp.setFCalendar(cal);

EntityManager em= getEntityManager(); //This op. obtains an EntityManager correctly.

em.getTransaction().begin();

em.persist(FCalendar.class, cal);

//Here I have cal as a managed entity. It points to the non-managed object comp.
//When the commit takes place, the table FCalendar of the DB will add a row for this calendar
//with the value "Cal111" as a primary key and "Comp111" for the column Competition
//(i.e., the foreign key of the competition associated to cal will refer to the competition "Comp111"
//since the DB contains a competition with the same id as cal.getCompetition() )

FCalendar caldb = em.find(FCalendar.class,cal.getFCalendarId());

//Now, I get a managed entity caldb which points to ANOTHER MANAGED ENTITY (let us call it 'compdb') which
//has as identifier "Comp111". This is the case, since the default fetch mode is EAGER for 1-1 associations.

Competition compdb = caldb.getCompetition();

//As I explained, compdb is a managed entity.

compdb.setFCalendar(caldb);

//In this way, I get the bidirectionality of the association. The managed competition compdb points now to the calendar caldb.

em.getTransaction().commit();

//The DB gets synchronized. The competition of the DB with id "Comp111" should point to the calendar "Cal111" and viceversa.

However, this is not the case. If I retrieve a competition from the DB with id "Comp111", its calendar associated is null (as if I did not set any calendar).

What am I missing, here???? I would be very grateful if someone can provide some clues.

(BTW, I have made this test with JPA and toplink as persistence provider)

Joe

Edited by: user632543 on Jun 2, 2013 4:50 AM

Edited by: user632543 on Jun 2, 2013 4:51 AM
  • 1. Re: find: Problems with keeping managed associated entities (1-1 associations)
    cdelahun Pro
    Currently Being Moderated
    You have not taken into account that there is a cache, and you are not maintaining it; you must set both sides of a bidirectional relationship to keep objects in synch with what is in the database.

    I am not sure how you have demarcated the transactions exactly, but unless you commit after you persist, are you sure you are getting a managed instance of Comp111 back from
    FCalendar caldb = em.find(FCalendar.class,cal.getFCalendarId());
    caldb.getCompetition();
    I assume that the FCalendar owns/controls the relationship, so that when the insert statement occurs the foriegn key is set correctly. As long as Competition is in the cache, it will show the stale null reference. This means that if you are not going to set the Competition back pointer in the entity, you will need to refresh the entity after the transaction commits to have the data reflect in the shared cache, and will need to clear other entityManagers that may already have it loaded. I would suggest you find the existing Calendar rather than create it, and set the backpointer on it:
    Competition comp = em.find("Comp111", Competition.class);
    ....
    FCalendar cal =new FCalendar("Cal111"); //"Cal111" is the identifier of this calendar object.
    cal.setCompetition(comp);
    comp.setCal(cal);
    comp.setFCalendar(cal);
    Best Regards,
    Chris
  • 2. Re: find: Problems with keeping managed associated entities (1-1 associations)
    635546 Newbie
    Currently Being Moderated
    Thank you very much for your answer. Asking in this forum helps me a lot since there are some aspectes of JPA which are tricky (at least, to me).

    If I do not misunderstand your answer, you mean that if my code is:
    em.getTransaction().begin();
    
    em.persist(cal);
    
    FCalendar caldb = em.find(FCalendar.class,cal.getFCalendarId());
    
    Competition compdb = caldb.getCompetition();
    
    em.getTransaction().commit();
    (where cal is a FCalendar with id= Cal111 which is linked to a competition with id. Comp111. The DB contains a competition with such id).

    The instruction:
    FCalendar caldb = em.find(FCalendar.class,cal.getFCalendarId()); 
    gets the calendar caldb from the DB and hence, caldb has not the link to Comp111 because the calendar with that link is in the cache (due to em.persist(cal); ) and will not be in the DB until commit is done???

    Is it that?


    I think that caldb should be managed (since it is obtained from a find within a transaction) and compdb should be managed too (since the association caldb-->compdb is 1-1, hence its retrieval is EAGER).


    Best regards and thank you very much, again.

    Joe.

    Edited by: user632543 on Jun 4, 2013 5:12 AM
  • 3. Re: find: Problems with keeping managed associated entities (1-1 associations)
    cdelahun Pro
    Currently Being Moderated
    Not quite what I meant. When you call persist, you are placing the entity instance in the EM's collection of managed entities. It will get synchronized with the database when the transaction commits or flushes.

    In your code:

    em.persist(cal);
    FCalendar caldb = em.find(FCalendar.class,cal.getFCalendarId());

    will result in cal == caldb. They are the exact same instance. Nothing gets put into the database until the transaction is flushed or committed, so the referenced Competition may be the empty instance you created as well instead of one read from the database. It is a bad idea to create empty instances of objects that exist in the database when you should be using a find or getReference instead. And you must set the backpointer in Competition.

    Best Regards,
    Chris
  • 4. Re: find: Problems with keeping managed associated entities (1-1 associations)
    635546 Newbie
    Currently Being Moderated
    Thank you very much. It is clear now.

    Joe.

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points