0

Why does opening an uninstantiated List of (entity) objects revert changes already made to any one of said objects within the same transaction?

Scenario:

  • A, B and C are all Entities
  • A holds a reference to a particular instance of B, retrievable with a.getB();
  • C has a list of B objects, retrievable with c.getListOfB()
  • The following is true: c.getListOfB().contains(a.getB())
  • The following has also been tested true: a.getB() == c.getListOfB().get(properIndex) (same object reference)

If I do the following within a transaction:

B b = a.getB();    
b.setOk(true); // <-- Changed from false to true

and then follow with:

c.getListOfB().isEmpty() // <-- Any function will do, I just used .isEmpty() to test it

Then b IMMEDIATELY has OK value set to false again :/

This happens within the same Transaction, before committing to DB.

Can someone please be so kind as to explain to me why EntityManager isn't aware of the changes already made to the above entity within the Transaction, and how to I can make sure it keeps them? This led me on a long bug hunt and I'm literally at loss of words on how to find any helpful results online.

EDIT: The problem is that when I instantiate the List with the .isEmpty() method, JPA reads the child objects from the DB "again", reverting the change I'd already made to one of its children earlier in the transaction. I feel that it SHOULD have known that one of the child objects was already IN the persistence context and not messed with it.

I'm currently working around the issue by calling c.getListOfB().isEmpty(), i.e. instantiating the List, BEFORE making the changes to b, but that is hardly a satisying solution, much less an explanation for the problem.

JohannSig
  • 131
  • 2
  • 8

2 Answers2

0

Make the variables static so that same instance is used.

Crickcoder
  • 2,135
  • 4
  • 22
  • 36
  • The same instance IS being used, according to a "==" check that I've amended to the scenario in my question. – JohannSig Aug 26 '13 at 03:45
0

a.getB() == c.getListOfB().get(properIndex) is not correct.

While comparing two object please use equals() method instead of "=="

== will compare object references.

equals() compare object properties.

In your case your need to compare the primary key of that object that is one property of the entity object.

The following is true: c.getListOfB().contains(a.getB())

The following is ALSO true: a.getB().equals(c.getListOfB().get(properIndex))

Not sure hibernate will return same referenced instance while calling a.getB() and c.getListOfB().get(properIndex) so dont use == while comparing two objecs properies

Prabhakaran Ramaswamy
  • 25,706
  • 10
  • 57
  • 64
  • But they ARE the same object reference, as tested for the scenario. The problem is that when I instantiate the List with the .isEmpty() method, JPA reads the child objects from the DB "again", reverting the change I'd made to one of its children earlier. It should instead have known that one of the child objects was already IN the persistence context and not messed with it. – JohannSig Aug 26 '13 at 09:53