Search code examples
javaspringhibernatejpatransactions

How to handle spring jpa @transactional and new inserts from catch block


I got this code. I am using spring boot and jpa

@Transactional

public class MyClass {

    public void createSomething() {
        try {
            saveAndFlush();
        } catch (Exception e) {
            // Since error has occured I want to insert this information
            // into a audit table

            repository.saveAndFlush();

        }
    }

}

Now when the exception happens, the transaction is rolled back and hence the error table insert is not happening.

I am seeing

HHH000099: an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session): org.hibernate.AssertionFailure: null id in XXXXX entry (don't flush the Session after an exception occurs)

In order to fix this I tried to do the error insert in a new method marked with @Transactional(propagation = Propagation.REQUIRES_NEW) on the understanding that the inner transaction would complete and outer would roll back

But I don't see my intended output.


Solution

  • Remove the @Transactional from class level, and use it on those methods which actually perform the transactions. (if you have more than 1 method in that class, of course).

    If you want independent transactions to commit/rollback to database, then use REQUIRES_NEW propagation on the method which will not disturb the global transaction.

    The default behavior of '@Transactional' without any propagation mentioned is, to join the global (calling) transaction if any available, and if not start a new transaction.

    Since you have a global transaction, it is rolledback completely. Instead, you need independent transactions.