在Spring和Hibernate中同时处理Controller,Service和DAO Layer异常的最佳实践是什么?

Nav*_*een 8 java spring hibernate exception

我正在开发Spring 3.2和Hibernate 3.6,任何人都可以解释如何处理Sping MVC和Hibernate中的异常......我只是分享示例代码.

控制器层

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

服务层

public Integer saveEmployee(Employee empObj){
    return masterDao.saveEmployee(empObj);
}
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)
  1. 现在假设任何异常发生在DAO层,同时节省了empObj像d/B了下来或连接失败或任何其他类型的Hibernate异常发生类似ConstraintViolationExceptionIntegrityConstraintViolationException等.

  2. 如果有可能NullPointerException在控制器层处理java异常或任何用户定义的异常等.

那么什么是最佳实践或如何同时处理Controller,Service和DAO Layer中的异常.

bee*_*jay 5

您不会同时处理应用程序所有级别的异常;您必须考虑它们的上下文含义以及适合您的应用程序的策略。有些错误应该被忽略,有些应该被包裹,有些应该允许直接引发。

spring-mvc应用程序中处理异常的一种方法是在适当的情况下用您自己的库包装来自底层库的致命错误,以它们被抛出的级别命名,例如ServiceExceptionRepositoryException。一@ControllerAdvice则-annotated类可以处理这些错误@ErrorHandler-annotated方法和返回5XXHTTP错误。

常见的应用程序错误,例如由于不正确而未找到实体id可能会导致自定义异常,例如NotFoundException引发并随后在您的@ControllerAdvice-annotated 类中捕获。

这种技术的优点是您在不同的应用程序层中有更少的错误处理代码,并且可以集中将异常转换为响应。

一个带@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);
    }
}
Run Code Online (Sandbox Code Playgroud)


cha*_*lvi 5

根据我在新项目中的经验,

  1. 您不应在DAO层处理异常。原因:通常我们在服务层放置@Transactional批注。因此,我们需要在服务层回滚事务。如果您在DAO处理异常,那么它将不会回滚。通过以下链接了解为什么我们应该在服务层放置@Transaction。
    “ @Transactional”应放在服务层或DAO的何处
  2. 您不应在服务层处理异常。原因:由于服务层为数据库操作执行了多个DAO,因此如果任何DAO失败,我们需要回滚事务。如果我们处理服务中的异常,那么我们可能不会回滚事务。对于回滚事务,有手动方法,但不建议这样做。TransactionAspectSupport.currentTransactionStatus()。setRollbackOnly();

因此在控制器层处理事务。