I’m using Hibernate 6.1.7 version.
When using queries in @Transactional processed methods, we often encounter an exception. What’s curious is that rollback works the same when using methods annotated with @Transactional (readonly=true).
Of course, I know that in general, we can handle exceptions with the noRollbackFor
option. However, when an exception is thrown from the query’s internal behavior, I have no control over the rollback behavior because Hibernate does the rollback marking on its own.
For example, If an exception is thrown in the find() method of org.hibernate.internal.SessionImpl, it bypasses the rollbackOn() method of the RuleBasedTransactionAttribute
and marks the rollback a priori as follows.
} catch (TypeMismatchException | ClassCastException | MappingException var20) {
throw this.getExceptionConverter().convert(new IllegalArgumentException(var20.getMessage(), var20));
also, the convert() method mark the rollback status like this
public RuntimeException convert(RuntimeException e) {
RuntimeException result = e;
if (e instanceof HibernateException) {
result = this.convert((HibernateException)e);
} else {
this.sharedSessionContract.markForRollbackOnly();
}
return result;
}
In this case, @Transactional will throw an Unexpectedrollbackexception at commit time, regardless of the noRollbackFor option.
This may be the default behavior for DB write operations, but I think it throws unnecessary exceptions for read operations. Is there any way to at least ignore the rollback on reading? Or, is there any way to avoid marking rollback in internal behaviors like find method?