Pete
Pete

Reputation: 10918

Catch Hibernate Persistence Exceptions in @Transactional REST service methods

We're building a REST service with Spring and JPA where each method is annotated @Transactional, since one REST call is one transaction. Now if say a user is trying to call delete on a resource that has dependencies, hibernate will throw a PersistenceException, causing the REST server call to return with status 500.

We want to catch those exceptions and wrap them in our own error object, that will contain custom error codes as well as the orignial message.

I tried just plain catching all RuntimeExceptions in the REST call and then returning our custom error object. That however won't work, as appearently the fact that the transaction has been aborted will get handled outside my method.

I also tried to catch the PersistenceException directly at DAO level. This worked fine in my unit tests didn't change anything outside them. Also our web container seems to just do its own thing by throwing a DataIntegrityViolationException instead of a PersistenceException. That doesn't even appear in the trace. As a side note, that's rather confusing, as I thought Hibernate would take care of its own stuff. Why is spring interfering?

Well anyway.. I also tried to use

TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

inside the REST service method with no success.

I'm at a loss here.. It seems error handling for a transaction started by @Transactional is just out of my hands..?! Is it maybe because the annotation creates a proxy that gets processed in a different scope?

Is the only option to handle transactions manually with the TransactionTemplate?

Upvotes: 1

Views: 1709

Answers (1)

Ralph
Ralph

Reputation: 120771

I expect that the exception will be thrown when one tries to commit the transaction. So you will not get the exception as long as you are inside of the transaction.

Spring will do something called Exception-Translation, this will "translate" some (vendor) specific exceptions into some other Spring Exceptions. I think this is the reason why you will notice the DataIntegrityViolationException

Upvotes: 4

Related Questions