I was using spring framework with hibernate (sessionFactory), and it seems that is impossible, because these are JPA callbacks that won't work with Session API, and to catch them we must use JPA implementation.
See http://stackoverflow.com/questions/4133287/preupdate-and-prepersist-in-hibernate-jpa-using-session
Hum, it seems that is time to move to full JPA and using standards seems to be a good thing. My application will be more portable (I never had an intention to switch from my good lightweight tomcat server to any of these big application server). What other? Ah, I can at anytime change the implementation (even if I really don't have any intention to move from Hibernation to TopLink or any other ORM).
Anyway, standard is standard and we all love standards (We will see that this is not always true)
So, I started working on a new branch: refact/entityManager and after 4 days refactoring the services/dao classes from Hibernate (Hibernate/SessionFactory) to JPA (Hibernate/EntityManager),
I just discovered that when inserting a duplicate entry, the transaction is rolled back and a TransactionSystemException is thrown and there is no mean to what was the culprit (the original cause). With session API I was able to know exactly what happened. ConstraintViolationException or DataIntegrityViolationException if spring exception translation is tuned on.
As I don't want to add a try-catch clause to the top-level method calling my transactional service method, and I don't want an extra select to check if a the entry already exists, I prefer the session API behavior and I will move back to Session API.
See thread on http://stackoverflow.com/questions/6040787/spring-exception-translation-isnt-working-with-jpa
So, how did you solved your problem then?
The solution is to use @Version as described here: http://notatube.blogspot.com/2010/03/hibernate-using-event-listener-to-set.html
private Timestamp lastModified; @Version public Timestamp getLastModified() { return lastModified; } public void setLastModified(Timestamp lastModified) { this.lastModified = lastModified; }Be sure to not have a method named onUpdate, as it is never called but make @Version fail silently. Change the method name, drop the table and create if you want @Version to work again"
Now, I'm happy with my good Hibernate/sessionFactory. May be one day, I'll try JDO, but I'll never play again with JPA/entityManager.
Extra Bonus: I don't want to loose my work
When in refact/entityManager branch, I have created a lot of test classes and I don't want to loose them.
Hopefully, git was there, suppose you are in master, just use:
git checkout refact/entityManager path/to/files ...sometimes we can check content of files from other branchs :
git show refact/entityManager:fileSource: http://stackoverflow.com/questions/449541/how-do-you-merge-selective-files-with-git-merge/1355990#1355990