Exception during multiload leaves EntityManager / Session and entities in an invalid state

Description

After a multiload with an exception during the hydrate phase of an entity, the entities that were loaded so far remain in the EntityManager / Session if the exception is caught. The entity that was loaded with error also remains partially hydrated. No @PostLoad callbacks are executed for the loaded entities.
If the same entity is loaded in the same transaction by another method (e.g. session.find(...) ), no error is thrown. Further, all entities that were loaded before the faulty entity can be retrieved from the session without ever having the @PostLoad method called on them.

There are several different options to deal with this:

  • Disable any access to the EntityManager / Session after an error in a multiload process

  • Purge eintities that were loaded before a faulty entity in a multiload from the EntityManager / Session

  • Ignore the error that the faulty entity caused, purge only the faulty entity from the EntityManager / Session and finish the multiload process (potentially repeat for other faulty entities, potentially throw an error nevertheless, after executing @PostLoad callbacks on all properly loaded entities)

The attached testcase shows a simple example where an invalid Enum case in the database causes an exception during the multiload and leaves several entities in an inconsistent state. See

Activity

Show:

Gavin King December 12, 2024 at 3:41 PM

From the Javadoc of Session:

It's crucially important to appreciate the following restrictions and why they exist:

  • If the Session throws an exception, the current transaction must be rolled back and the session must be discarded. The internal state of the Session cannot be expected to be consistent with the database after the exception occurs.

  • At the end of a logical transaction, the session must be explicitly destroyed, so that all JDBC resources may be released.

  • A Session is never thread-safe. It contains various different sorts of fragile mutable state. Each thread or transaction must obtain its own dedicated instance from the SessionFactory.

This is also very clearly called out in the Hibernate documentation.

Christian Beikov December 12, 2024 at 2:47 PM

When an error occurs during flushing or loading, a Hibernate Session is not supposed to be used any further, so this is not a bug. You're only supposed to end an open transaction and call Session.close(), but not interact with a session any further.

Tassilo Karge August 9, 2021 at 1:20 PM

I am willing to contribute a solution if a decision for one of the above variants for the solution is made by the maintainers.

Tassilo Karge August 9, 2021 at 12:19 PM

Test cases in PR

Rejected

Details

Assignee

Reporter

Labels

Components

Priority

Created August 9, 2021 at 11:51 AM
Updated December 12, 2024 at 3:41 PM
Resolved December 12, 2024 at 2:47 PM