2
votes

I am writing a REST application using Spring. It is divided into 3 layers, controller, service and repository.

The repository layer are using Spring data and MongoDb. The exceptions from MongoDb are translated to Spring Data exceptions.

Using the @ExceptionHandler annotation I tried to catch those exceptions in the repository layer. This did not work. The only way to catch the exception with @ExceptionHandler is to put the code in the controller layer.

Is there a way for me to catch and handle the exceptions in the repository layer,, without using try/catch blocks.

1
It's the repository layer (i.e. the Spring proxies around your repositories) that throw these exceptions, so I don't see how you could catch the in the repository layer. What's the point, anyway? - JB Nizet
Handling the exception as close as possible to the origin. - lg.lindstrom
In this case, it would mean catching the exception before it has even been thrown. You could catch them in the service layer, but what would be the point? Could you do anything other than what is done by default (rollbacking the transaction and propagate the exception). - JB Nizet
How do I catch them in the service layer without using a try/catch block? - lg.lindstrom
I don't know, because I still don't understand why you want to catch the exception. - JB Nizet

1 Answers

4
votes

It could be done with Spring AOP and by creating an @Around advice for all your DAO methods as shown below.

But I would still like to understand what you plan to do in your catch block. Are you planning to have different logic to handle different types of data access exceptions? If you don't have any specific logic, it makes sense to just let the exception propagate to the controller layer.

First Option

Here is a sample -

    @Aspect
public class DaoExceptionHandlerAdvice {
    @Around("execution( * com.xyz.daos.*.*(..))")
    public Object invokeService(ProceedingJoinPoint pjp) throws Throwable{
        MethodSignature methodSignature = (MethodSignature)pjp.getSignature();
        Object returnValue = null;
        try {
            returnValue = pjp.proceed();
        } 
        catch(Exception e){
            // handle the exception 
        }
        finally{
        }
        return returnValue;
    }
}

Add following snippet in your application context file

<aop:aspectj-autoproxy />    
<bean id="daoExceptionHandler" class="com.xyz.advice.DaoExceptionHandlerAdvice"  ></bean>

Check out the following link for details - Spring AOP

Second Option

I've not tried this, but it would probably be easier for you to use an exception translator. You could probably extend HibernateExceptionTranslator and have your own logic in there.

Follow this link for details - Exception Translation