I didn't know if it was appropriate to delete the original question but have added a more concise explanation at the bottom hopefully eliminating the need to review all of the details.
I am receiving inconsistent results and can't figure out what I am doing wrong. It relates to an EE7 web app with container managed Entity Manager, Java 8, EclipseLink 2.5.2, netbeans 8.0.2 IDE.
There is a parent child relationship mapped as a bi-directional relationship:
Event Table is the parent which maps to Games
@OneToMany(fetch=FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "event")
@OrderBy("gameType, round")
private List<Game> gameList;
Games maps the Event as
@JoinColumn(name = "EVENT", referencedColumnName = "ID")
@ManyToOne(fetch = FetchType.EAGER, optional = false)
private Event event;
Step 1: Using a web interface I create an event and one game. The game is added to the event list and event to the game. em.persist(event) is called to save all of it. -> works great
Step 2: Edit the event create a new game - Add the event to the game, em.persist(game) with em.flush() to get the id and add it to the game list in events After all editing is done em.update(event) -> database updates exactly as expected -> BTW I understand that it is a better user experience to not persist game until the event is ready to be saved to allow option of 'quit'. It is something I plan to do but don't yet have a good handle on best practices for doing so and my experience with cascade is mixed.
Finally the issue: - 100% of the time 'step two' works correctly with the database but when I retrieve the event for further edits the event has an additional entry in the game list with value of null. - if I shut down and restart the app over and over sometimes it happens and sometimes it doesn't. The database always remain in tact and exactly as expected - simultaneously using a different browser from the same machine or others has the same result - obviously the persistence cache CAN get in an inconsistent state but I have not been able to determine if I am doing something wrong or experiencing an EclipseLink bug
Earlier I reported a problem that turned out to be an EclipseLink bug related to the IndirectList class and Java 8 so I am not sure if I am doing something wrong or if this is similar.
Thanks in advance!
After some reading through the JPA JSR I am wondering if my understanding is correct. Using the EE container managed transaction scoped persistent context in a web application essentially means a transaction begins with a method call to the EJB and end with the return. Therefore getting info to put something on a screen is one transaction and updating after the users changes is another. Or more clearly, I am almost always working with detached entities.
My approach has been to get the entity tree, let the user/administrator update whatever is necessary and then persist, merge or delete as appropriate. Since it is detached orphan removal doesn't work so I do that directly but maintain the relationships. I also persist the new children directly and presume I can em.merge the parent as much as I want because it becomes attached, applies the changes and my entity is in tact with the DB.
Is that a fair approach or is it it flawed somehow?
I am still having this issue and have possibly tracked it a little further. I have a number of related records with bi-directional links via foreign keys @ManyToOne and @OneToMany.
It is essentially a simple chain with backward links:
- Entity A contains a List of B, and B a foreign key to A
- Entity B contains a List of C, and C a foreign key to B
Steps to reproduce:
- new C(B, and other constructor parameters)
- B.add(C)
- Set other properties in C
- em.persist(C) to ensure an ID
- em.update(B) to register updated relationship
After every step including 4, everything looks correct. I thought perhaps step 2 should follow 4 but am not sure it would make a difference. After step 5,
- B has the same memory location and pointer to C.
- C has been updated with NEW memory locations for the references to B and A.
- i.e. the pointer back to B and A in C is a different memory location than the source
Subsequently when I refresh the entity with a em.find(), entity B has NULL entries in List C although the MySQL database reflects what I expect.
I have obviously done something wrong which has corrupted the EclipseLink persistence cache. The only thing I have found to fix this is restarting the app to delete the cache.
I have not been able to resolve this for months and would appreciate any advice.