Skip to content
Advertisement

Hibernate how to commit transaction even when exception pops up

i have a method in Service A

@Transactional
public void doSomething() {
  for (int i = 0; i < 100; i++) {
    anotherService.doThing();
  }
}

And another method in Service B

@Transactional(propagation = REQUIRES_NEW, noRollbackFor = RuntimeException.class)
public void doThing() {
  ...
  try {
    repository.insertRandomValue();
  } catch (Exception ignored) {
  }      
  ...
}

My problem is that when “repository.insertRandomValue()” throws ConstraintViolationException for example, then even tho it was caught in catch(), the thread ends with

org.springframework.transaction.UnexpectedRollbackException: Transaction silently rolled back because it has been marked as rollback-only

I have tried setting the propagation to REQUIRES_NEW and tried to set up transaction manager and GlobalRollbackOnParticipationFailure to false.

@Bean
public JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
  JpaTransactionManager manager = new JpaTransactionManager(entityManagerFactory);
  manager.setGlobalRollbackOnParticipationFailure(false);
  return manager;
}

I want it to simply ignore the failed insert attampts and continue working. Does anyone have an idea how to achieve that?

Advertisement

Answer

The Hibernate documentation is very clear that you have to rollback (section 5.16 Exception Handling):

If the JPA EntityManager or the Hibernate-specific Session throws an exception, including any JDBC SQLException, you have to immediately rollback the database transaction and close the current EntityManager or Session.

Certain methods of the JPA EntityManager or the Hibernate Session will not leave the Persistence Context in a consistent state. As a rule of thumb, no exception thrown by Hibernate can be treated as recoverable. Ensure that the Session will be closed by calling the close() method in a finally block.

Rolling back the database transaction does not put your business objects back into the state they were at the start of the transaction. This means that the database state and the business objects will be out of sync. Usually, this is not a problem because exceptions are not recoverable and you will have to start over after rollback anyway.

So you need to check beforehand if there would be a ConstraintViolationException

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement