Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Howto compare two entities in JPA onPreUpdate [duplicate]

I am working with OpenJPA 2.2.1 and would like to do the following:

1) Load an entity 2) Change the entity 3) Check the changes done before saving the entity

What I've done:

1) Load the entity via

    EntityManager.find(MyObject.class, id);

2) Ok, pretty clear, I think, something like

    MyObject obj = EntityManager.find(MyObject.class, id);
    obj.setName("New name");

3) Tried to evict the object from the PersistenceContext and loading it again from the database via:

    EntityManager.evict(MyObject.class, id);
    EntityManager.find(MyObject.class, id);

The entity returned by the find() call in 3) is always equal (equal ID) to the entity found in 1)

I thought I could remove the entity from the PersistenceContext / cache by evict.

How can I achieve to have two different entities: a) the changed entity and b) the original entity from the database loaded in step 3)

And: If i refresh() the entity I expect the find method to return the refreshed one. Is that correct?

I tried the @PreUpdate listeners too with the same result so I think there must be something I have not understood regarding JPA PersistenceContext or Java references...

I hope I provided enough information! Thanks in advance!

like image 753
4thfloorstudios Avatar asked Oct 24 '25 19:10

4thfloorstudios


1 Answers

For a good overview of the JPA lifecycle I found this site (particularly the state diagram) to be helpful: http://www.objectdb.com/java/jpa/persistence/managed

The main take-away is that objects don't "disappear" when you remove them from the persistence context. Your obj will still point to a fully initialized MyObject with name set to "New name". The only difference is that committing the transaction/flushing the persistence context will no longer update the corresponding database entry.

You have several options when you want to look at the changes to obj before committing to the database. If quick and dirty suffices, I'd suggest

MyObject original = obj.clone();

and compare obj and original with whatever tool (or just plain printing both to your log) you like.

Regarding refresh(), have a look at what this page says:

The content of the managed object in memory is discarded (including changes, if any) and replaced by data that is retrieved from the database. This might be useful to ensure that the application deals with the most up to date version of an entity object, just in case it might have been changed by another EntityManager since it was retrieved.

like image 154
mabi Avatar answered Oct 26 '25 08:10

mabi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!