简体   繁体   中英

Unable to wrap DAO exception in service layer using Spring MVC

I am trying to handle custom exception handling using Spring MVC. DAO layer exception handler by service layer and service layer wrap that exception and handle that exception by Controller exception handler by Spring MVC. Following is my code:

@Override
public void saveNewMachineDetails(Machine machine, Configurations configurations) throws DataNotPersist{
logger.info("call service saveNewMachineDetails method");

try{
    machineRepository.saveAndFlush(machine);
}catch(Exception ex){
//  logger.error(ex.getMessage());
    DataNotPersist dataNotPersist =  new DataNotPersist(messageSource.getMessage("code.object.notpersist", null, null), 
            messageSource.getMessage("msg.object.notpersist", new Object[]{"Machine"}, null), ex);
    throw dataNotPersist;
}}

In the above code the DAO layer exception handle at service layer and wrap that exception in custom exception and throw that exception.

In web layer i have configure Exception handler for handling exception, but when the exception is throw, the handler not catch the exception, i think because of i am unable to wrap actual exception with custom exception. Following is my exception handler code:

@ControllerAdvice
public class GlobalExceptionHandler {

private Logger logger =    LoggerFactory.getLogger(GlobalExceptionHandler.class);

@ExceptionHandler(value = DataNotPersist.class)
public ModelAndView defaultExceptionHandler(HttpServletRequest request, DataNotPersist ex)throws Exception {
logger.info("In GlobalExceptionHandler");

logger.debug("********* : "+ex.getMessage());

ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("exception", ex);
modelAndView.addObject("url", request.getRequestURL());
modelAndView.setViewName("common/error");
return modelAndView;
}}

In service layer when i throw the exception, spring roll back the transaction and wrap my Exception into TransactionException at view. Now i handle the transaction rollback with my Exception class as below:

@Override
@Transactional(value="transaction_manager", rollbackFor={DataNotPersist.class})
public void saveNewMachineDetails(Machine machine, Configurations configurations) throws DataNotPersist{
    logger.info("call service saveNewMachineDetails method");

    try{
        machineRepository.saveAndFlush(machine);
    }catch(DataAccessException ex){
        logger.error(ex.getMessage());
        DataNotPersist dataNotPersist =  new DataNotPersist(messageSource.getMessage("code.object.notpersist", null, null), 
                messageSource.getMessage("msg.object.notpersist", new Object[]{"Machine"}, null), ex);
        throw dataNotPersist;
    }}

The ControllerAdvice will not catch the exceptions that happen in the service layers. From the docs

It is typically used to define ExceptionHandler methods that apply to all @RequestMapping methods.

So in order for the ControllerAdvice method to take effect, your controller method must throw the DataNotPersist exception

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM