While updating from Hibernate version 3 to version 4 a few months ago on the project i'm working on, I had a really good proof that, when working with a complex framework like Hibernate, the developer must read the documentation very carefully in order to prevent the usage of "non-standard" solutions that may have to be modified in the future when the framework is updated.
In this project, there's sometimes a need to delete some entries on a table but, if some entry is referenced somewhere else (by a foreign key) we don't delete the entry, instead there's a column called
Active that's updated to
False. For example, there's a
Store table and a
Customer table that has a foreign key to
Store and when someone tries to delete an entry on
Store that is referenced by one or more entries of
ConstraintViolationException is thrown. We were then catching the exception and reusing the same session to update the
Active column to
False. A sample of the code might help to understand this situation:
If the Session throws an exception, including any SQLException, immediately rollback the database transaction, call Session.close() and discard the Session instance. Certain methods of Session will not leave the session in a consistent state. No exception thrown by Hibernate can be treated as recoverable. Ensure that the Session will be closed by calling close() in a finally block.
And if you notice on the links to the hibernate documentation, this was for version 3.5 but it's also on version 4. I don't know if someone on my dev team read this paragraph before going for the solution I previously presented and ignored it because, well, it just worked, or if the documentation was treated as "just some set of letters that explain the framework with too much detail but doesn't give solutions for real problems".
In conclusion, we had to refactor some code in multiple places where this was being done and now we don't delete anything, we just update
False and then from time to time a procedure is run to delete items that are inactive and aren't referenced by other entities.
Note: If you want to get your hands dirty, I set up a project using Hibernate 3 and another one with Hibernate 4 that replicate the problem previously described. Oh, and here's an sql dump of the PostgreSQL database I used for this example.