I'm using Spring Boot with JPA and Hibernate. I have a table with one unique constraint because I would like to avoid having multiple rows.
In my business logic method, I have to save multiple rows and I would like to add the @Transactional
because I need to rollback in case of some errors occurring during some saves.
For me, the DataIntegrityViolationException (the constraint is violated) is not an error and in this case I would like to avoid the rollback (if the row already exist I need to go on with the others saves).
I tried multiple solution just to setup my @Transactional
to skip the rollback in case of DataIntegrityViolationException (for example in this case @Transactional(rollbackFor = Throwable.class, noRollbackFor = DataIntegrityViolationException.class)
) but this not works and I receive:
UnexpectedRollbackException: Transaction silently rolled back because it has been marked as rollback-only
Any idea?
CodePudding user response:
Try just to surround your statement that throws the DataIntegrityViolationException
exception with a try catch
and in the catch
block just print the error avoiding to throw a DataIntegrityViolationException
exception followed by a rollback.
CodePudding user response:
@Transactional(noRollbackFor = DataIntegrityViolationException.class)
is going to work, but you have to put it on your repository method, not the service one.
public interface SomeRepo extends JpaRepository<_, _> {
@Transactional(noRollbackFor = DataIntegrityViolationException.class)
void someUpdate(...);
}
The reason the rollback does not occur in your case is that the exception gets thrown from the transactional proxy that is not marked to skip those types of errors.
I wrote an article about this nuance. Perhaps, that will help to clarify the point.