I have the following tricky situation in my Spring Boot application that uses Hibernate. I load objects from the data store and I modified them in several functions of my application that are not related one with another. The idea is that I need to load the existing copy of the object from the database before saving its update instance in order to create a backup, but if I use the repository's findById
method, Hibernate finds a copy of the object (the modified one) in its cache and returns that one and it is not ok for me, because I need a copy of the original object, before it was modified (the object that is currently in the database). I tried using a separate Session, but in case of multiple objects the DB is locked and I'm not able to access the database anymore (MS Sql Express). Has anyone an idea on how to obtain the original unmodified object before persisting tghe changes in the database ? Thanks
Asked
Active
Viewed 340 times
0

Sergiob
- 838
- 1
- 13
- 28
-
If you use the Session object, method get, should return what you want. See: https://www.dineshonjava.com/difference-between-get-and-load-methods-in-hibernate/ – pringi Mar 23 '22 at 14:17
-
1Perhaps _in order to create a backup_ should be moved from the app's responsibility to the database's responsibility, .e.g., use insert/update database triggers to store changes (backup/audit) in another table. The app could query against the historical table if a previous version is really needed. – Andrew S Mar 23 '22 at 14:18
-
@AndrewS it is not about a database backup, it is about a tracking system. Every time an object is modified I need to keep a copy of its previous state – Sergiob Mar 23 '22 at 14:43
-
@pringi. it doesn't work, if I run 3 times in a row the same statement it locks the table – Sergiob Mar 23 '22 at 15:06
-
Are you calling your findById method in the same transaction ? Have you tried to call the findById method in a new transaction ? You can annotate your method with @Transactional(propagation = REQUIRES_NEW) to be sure to use a new one – Bad_Pop Mar 23 '22 at 15:18
-
I've tried a work around but the get method described at your link doesn't return the row from the DB, it returns the cached object – Sergiob Mar 23 '22 at 16:14
-
@Bad_Pop I cannot spawn too many transactions. The obejct is anyway searched by another session => new transaction – Sergiob Mar 23 '22 at 16:42
1 Answers
0
To keep backup of entities you should use @Audited (it keeps versions / snaphshots of each entity).
You can have a look over there https://www.baeldung.com/database-auditing-jpa
A more advanced approach is https://javers.org/.
Javers is the state-of-the-art way to do what you want to do. I think it will suit your needs.

XII
- 420
- 4
- 16
-
Both are good ideas but they do not solve my problem. Auditing gives me the possibility to intercept the change event, not to get an instance of the original object that is in the database, Javers is completely out of scope, I do not need a tool for versioning my tables. My problem is much simpler. I need an instance of the entity before it was changes (in other words ... mirroring what is in the DB before saving), bypassing Hibernate cache that always contains the modified one and I do not want to instantiate a new Session. – Sergiob Mar 24 '22 at 14:05
-
Ok my bad , then maybe something like this https://stackoverflow.com/questions/27905148/force-hibernate-to-read-database-and-not-return-cached-entity ? – XII Mar 24 '22 at 14:20