The behaviour you mention is by design for a persistence context (PC). The possible options depend on whether you want the
version in the database right nowor, rather,
the version I loaded in the current PC.
- Hibernate maintains an internal snapshop of the loaded entity, but I don't know if there is a public API to access it
- another option would be to use a Hibernate filter or a @PostLoad method to keep it the original value
- yet another one is to use a native query (which bypasses the PC). Note that this may see a more recent version of the entity in case it was modified by another transaction.
- maybe Hibernate Envers has something here, I haven't checked
- or you may rethink how you do auditing (in case this was the business purpose behind the question).
Thanks for your quick answer.
I've searched for accessing the loaded entity but AFAIK no API exists for that purpose.
@PostLoad and native query seems the best ways for accessing it. One uses more memory at load time, other accesses the db one more time than the other. The main reason to ask the question, really points to the 5th topic. I have to store the revisions of a record in a log db. If you have suggestions, other than this, about the way to solve the problem I can take advice ;).Thanks again.
You could define another entity manager and use it to obtain the original values
Components.xml <persistence:managed-persistence-context name="logEntityManager" auto-create="true" persistence-unit-jndi-name="java:/myEntityManagerFactory" />
@PostUpdate EntityManager em = (EntityManager)Component.getInstance("logEntityManager"); //do your query to get the original values here //write before/after images to db here
You will also require a separate Entity Manager to write the before/after logs, because you are not allowed to perform any operations that would change the state of the entity manager during execution of a callback method.
I would also look into Envers ...
refer to 12.3.2 Intercepting Hibernate events and 12.3.4 Entity listeners and callbacks in JPA/Hibernate book for audit logging coverage.
I'm using a second manager to log the old values to log db(thus the logging process persists to another db) I've overrided the persist,update,remove methods entityHome classes generated by seam, made them transactional and bind them to xa-datasources. Everything works fine . The only problem was , when I try to persist the old values to log db I can not access them from manager. The reply Jean gave solved the problem. I'll have a look at the sections that Arbi mentioned in the response for better alternative.
Thanks for your help.
The problem with a second EM is that it loads what is then in the database, not what you loaded. You have to take versioning into account in order to get correct auditing. It may be better to save the new version immediately to the audit table as well, instead of trying to save the previous version when a new one is created. Space is not an issue and this ensures correctness. You also don't need a separate EM.