Search code examples
javajpaeclipselink

JPA (EclipseLink) returning null in list


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:

  1. new C(B, and other constructor parameters)
  2. B.add(C)
  3. Set other properties in C
  4. em.persist(C) to ensure an ID
  5. 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.


Solution

  • The problem was ultimately tracked to a coding error. Specifically the reference pointer returned from em.merge() was not updated in the related entities resulting in multiple copies and corrupting persistence.

    Something in the startup sequence affected whether this corruption became evident with the symptom of null's in a list or everything working fine. It appeared sporadic but in fact was the result of the earlier corruption.