0

Testing my application I decided to shutdown the database.

public Object getEntityById(Class<?> clazz, Object _id) throws PersistenceServiceException {
    Object o = null;
    try {
        o = entityManager.find(clazz, _id);
    } catch (Exception e) {
        throw new PersistenceServiceException(e);
    }
    return o;
}

so, any database exception should be passed to the caller.

and in the controller I have

    try {
        template = (Template)persistenceService.getEntityById(Template.class, id);
    } catch (PersistenceServiceException e) {
        response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        response.setStatusMessage("INTERNAL SERVER ERROR");
        response.setData(e);
        return  response;
    }

when debugging, I can see the DatabaseException been throw.

but in servlet-context, once I have this...

<beans:bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <beans:property name="defaultErrorView" value="core/error.uncatched" />
</beans:bean>

it keeps treating the above error as unhandled.

How can I catch it on the controller? Why is it happening?

The Exception

ERROR: org.springframework.transaction.interceptor.TransactionInterceptor - **Application exception overridden by commit exception**
com.company.exceptions.PersistenceServiceException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.6.0.v20130619-7d05127): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
Ruben Trancoso
  • 1,444
  • 5
  • 27
  • 55

3 Answers3

0

You should use PersistenceException to catch exception .Because you are using JPA.

Diptopol Dam
  • 823
  • 1
  • 10
  • 39
0

The true is that the Transactional context is throwing a TransactionSystemException (a RunTimeException), so the wrapped excetion I did is been wrapper again by the TransactionSystemException. This last one need to be added to the catch clause in the controller.

Anyway I not mark it as correct right now. If somebody wants to add something, is welcome.

Ruben Trancoso
  • 1,444
  • 5
  • 27
  • 55
0

The stacktrace shows these two exceptions:

Internal Exception: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

It means that the database is not reachable. Which is because you have shutdown the database. Here is a discussion about this exception.

ERROR: org.springframework.transaction.interceptor.TransactionInterceptor - Application exception overridden by commit exception

The default configuration of Spring framework's transaction infrastructure marks a transaction for rollback only when the thrown Exception is an unchecked exception. If you have defined the PersistenceServiceException as a checked exception, it will not cause rollback in Spring transaction. You are catching an unchecked exception (in your getEntityById method), converting it to a checked exception and then you are throwing this checked exception.

To solve this you can configure the transaction infrastructure to rollback the transaction for PersistenceServiceException by

Changing the PersistenceServiceException into a runtime exception (PersistenceServiceException extends RuntimeException)

or by annotating your service with

@Transactional(rollbackFor = PersistenceServiceException.class)

Community
  • 1
  • 1
Debojit Saikia
  • 10,532
  • 3
  • 35
  • 46