在Spring和Hibernate中同时处理控制器层、服务层和DAO层异常的最佳实践是什么

5f0d552i  于 2023-01-05  发布在  Spring
关注(0)|答案(3)|浏览(130)

我正在开发Spring3.2和Hibernate 3.6,有没有人能解释一下如何在SpringMVC和Hibernate中处理异常......我只是在分享示例代码。
控制器层

public Integer saveEployee(HttpServletRequest req, HttpServletResponse res){
    Employee empObj = new Employee();
    empObj.setName(req.getParameter("empName"));
    ......................
    ......................
    Integer empId = materService.saveEmployee(empObj);
    return empId; 
}

服务层

public Integer saveEmployee(Employee empObj){
    return masterDao.saveEmployee(empObj);
}

DAO层

public Integer saveEmployee(Employee empObj){
    Session session = sessionFactory.openSession();
    Transaction tx = session.beginTransaction();
    Integer empId = session.save(empObj);
    tx.commit();
    session.close();
    return empId;
}

1.现在假设在DAO层保存empObj时发生了任何异常,比如d/b关闭或连接失败,或者发生了任何其他类型的休眠异常,比如ConstraintViolationExceptionIntegrityConstraintViolationException等。
1.是否有可能在控制器层处理NullPointerException等java异常或任何用户定义的异常等。
那么什么是最佳实践或者如何同时在控制器、服务和DAO层处理异常。

ckocjqey

ckocjqey1#

根据我在新项目中的经验,
1.不应该在DAO层处理异常。原因:通常我们把@Transactional注解放在服务层。因此我们需要回滚服务层的事务。如果你在DAO处理异常,那么它将不会回滚。跟随下面的链接了解为什么我们应该把@Transaction放在服务层。
Where should "@Transactional" be placed Service Layer or DAO
1.不应在服务层处理异常。原因:由于服务层执行多个DAO进行数据库操作,如果任何DAO失败,我们需要回滚事务。如果我们在服务中处理异常,那么我们可能不会回滚事务。有手动回滚事务的方法,但不建议使用。TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
因此,在控制器层处理异常。

dauxcl2d

dauxcl2d2#

您不能同时处理应用程序所有级别的异常;你必须考虑它们的上下文含义和你的应用程序的适当策略。2一些错误应该被忽略,一些应该被 Package ,一些应该被允许直接引发。
spring-mvc应用程序中处理异常的一个方法是在适当的地方用你自己的库 Package 来自底层库的致命错误,以抛出它们的级别命名,例如ServiceExceptionRepositoryException。然后,一个@ControllerAdvice注解的类可以用@ErrorHandler注解的方法处理这些错误,并返回5XX http错误。
常见的应用程序错误,比如由于id不正确而导致实体未被找到,可能会导致自定义异常,例如NotFoundException被引发并随后在您的@ControllerAdvice注解类中被捕获。
这种技术的优点是在不同的应用程序层中有较少的错误处理代码,并且可以集中异常到响应的转换。
一个示例@ControllerAdvice注解类:

@ControllerAdvice
public class ErrorHandler extends ResponseEntityExceptionHandler {
    @ExceptionHandler({NotFoundException.class})
    protected ResponseEntity<Object> handleNotFound(RuntimeException e, WebRequest request) {
        return handleExceptionInternal(e, e.getMessage(),
                null,
                HttpStatus.NOT_FOUND, request);
    }

    @ExceptionHandler({ServiceException.class, RepositoryException.class})
    protected ResponseEntity<Object> handleInternalError(RuntimeException e, WebRequest request) {
        return handleExceptionInternal(e, e.getMessage(),
                null,
                HttpStatus.INTERNAL_SERVER_ERROR, request);
    }
}
vu8f3i0k

vu8f3i0k3#

您应该使服务具有事务性,并在控制器层处理异常:您可以选择基于控制器的异常处理(使用@ExceptionHandler)或全局异常处理(使用@ControllerAdvice类)。2在发生异常时,向用户显示一些信息(例如错误页面)可能比较实用。
您可以在Spring MVC here中找到异常处理的有用示例。

相关问题