Rollback transaction after exception in JPA + Spring

I use Spring and JPA along with HIbernate. When a PersistenceException is thrown, I want to catch it and return an error message so that it does not propagate to the caller.

@Transactional public String save(Object bean) { String error = null; try { EntityManager entityManager = getEntityManager(); for (int i = 0, n = entities.size(); i < n; i ++) { entityManager.merge(entities.get(i)); } } catch (PersistenceException e) { error = e.getMessage(); } return error; } 

But I get an exception saying javax.persistence.RollbackException: Transaction marked as rollbackOnly. I get that the transaction should be rolled back after the exception, but how to return it when I caught the exception and do not want to throw it again?

+4
source share
4 answers

It seems that it is not possible to undo a failed transaction managed by Spring ORM. The code shown in the question is a class of service. Fetching its persistence procedure into a separate DAO class and having a PersistenceExceptions service class handle did the trick.

+2
source

Using @Transactional , if there are any RuntimeExceptions in the method, it will automatically roll back. You do not need to do this manually. You should probably not catch this exception at all and instead pass it to a higher level ExceptionHandler, which shows the user some standard error page (not a stack trace). Also your method is marked as void, but you are returning a string.

+4
source

You can use Spring Exception Translation with a custom PersistenceExceptionTranslator to throw a PersistenceException into something useful.

Oh, by the way, you shouldn't use @Transactional at the DAO level. Transactions must be run at the service level.

+4
source

Use @Transactional(noRollbackFor={PersistenceException.class}) for the method that throws the exception.

0
source

Source: https://habr.com/ru/post/1340848/


All Articles