Search code examples
javaspringinterceptorchecked-exceptions

Interceptors Java and checked exception


I am using Spring's AOP feature. I have class called

class UserService {
    public User insertUserService(User user) throws PersistenceLayerException {
        System.out.println("UserServiceImpl_Two called: insertUserService method");

        if (user.id == 1) 
            throw new PersistenceLayerException();

        return null;
    }
}

Now, the calls to this method insertUserService are intercepted by an interceptor which does some validation. This validation interceptor throws a checked exception called BusinessException. Now, when this exception is thrown, Java throws an UndeclaredThrowableException because BusinessExcepetion is not declared in the throws of insertUserService. Is there a way to get around this UndeclaredThrowableException without having to declare the BusinessException in the throws clause.

The reason being there in nothing in insertUserService itself that throws a BusinessException, so its appear there should be way around.


Solution

  • One idea, if it's feasible, would be to make BusinessException a subclass of RuntimeException, which is more in line with Spring philosophy anyway.

    EDIT:

    You also asked if there's a way to do this with checked exceptions. One approach you might take is based on rethinking your UserService contract. "Services" (in the service bean sense) are usually higher level domain concepts, so it might actually be more appropriate to declare BusinessException from your UserService contract anyway. Then when there's a lower-level persistence issue, you can either wrap that with the BusinessException (if BusinessException means something generic like "the call to the business service failed"), or else just declare both BusinessException and PersistenceLayerException if you want BusinessException to have a narrow meaning (e.g. validation issues and the like).

    In this case, you might be using UserService as a Spring Security UserDetailsService, which really is more persistence-oriented. If so then the thoughts above may not apply. But otherwise consider that an option.

    Having said all that, making BusinessException a RuntimeException is the most consistent with Spring practice, and arguably a best practice for reasons I describe here.