This content has been marked as final.
Show 4 replies
-
1. Re: find: Problems with keeping managed associated entities (1-1 associations)
Cdelahun-Oracle Jun 3, 2013 1:19 PM (in response to 635546)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
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:FCalendar caldb = em.find(FCalendar.class,cal.getFCalendarId()); caldb.getCompetition();
Best Regards,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);
Chris -
2. Re: find: Problems with keeping managed associated entities (1-1 associations)
635546 Jun 4, 2013 12:13 PM (in response to Cdelahun-Oracle)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:
(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).em.getTransaction().begin(); em.persist(cal); FCalendar caldb = em.find(FCalendar.class,cal.getFCalendarId()); Competition compdb = caldb.getCompetition(); em.getTransaction().commit();
The instruction:
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???FCalendar caldb = em.find(FCalendar.class,cal.getFCalendarId());
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-Oracle Jun 4, 2013 12:49 PM (in response to 635546)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 Jun 4, 2013 1:48 PM (in response to Cdelahun-Oracle)Thank you very much. It is clear now.
Joe.