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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29731353/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 15:48:50  来源:igfitidea点击:

What are the best practices to handle exception at Controller, Service and DAO Layer simultaneously in Spring & Hibernate

javaspringhibernateexception

提问by Naveen

I am working on Spring 3.2 & Hibernate 3.6, can any one explain how to handle exception in Sping MVC & Hibernate...i just sharing sample code.

我正在研究 Spring 3.2 和 Hibernate 3.6,谁能解释一下如何在 Sping MVC 和 Hibernate 中处理异常...我只是分享示例代码。

Controller Layer

控制器层

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

Service Layer

服务层

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

DAO Layer

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. Now suppose any exception occurred at DAO layer while saving the empObj like d/b got down or connection failed or any other kind of hibernate exception occurred like ConstraintViolationExceptionor IntegrityConstraintViolationExceptionetc.

  2. If there is chances of java exception like NullPointerExceptionor any user defined exception etc to be handle at Controller layer.

  1. 现在假设任何异常发生在DAO层,同时节省了empObj像d / B了下来或连接失败或任何其他类型的Hibernate异常发生类似ConstraintViolationExceptionIntegrityConstraintViolationException等。

  2. 如果有机会NullPointerException在控制器层处理像 Java 异常或任何用户定义的异常等。

So what are the best practicesor how to handle the exception at Controller, Service and DAO Layersimultaneously.

那么什么是最佳实践或如何同时处理控制器、服务和 DAO 层的异常。

回答by chaitanya dalvi

As per my experience during new project,

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

  1. You should not handle exception at DAO layer. Reason: Normally we place @Transactional annotation at Service Layer. hence we need to rollback transaction at service layer. If you handle exception at DAO then it will not rollback. Follow below link to know why we should place @Transaction at Service Layer.
    Where should "@Transactional" be place Service Layer or DAO
  2. You should not handle exception at Service Layer. Reason: As service layer execute multiple DAO for DB operation and we need to rollback transaction if any DAO fails. If we handle exception in service then we may not rollback transaction. There is manual approach for rollback transaction but it is not recommend. TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
  1. 您不应该在 DAO 层处理异常。原因:通常我们在服务层放置@Transactional注解。因此我们需要在服务层回滚事务。如果您在 DAO 处理异常,则它不会回滚。按照以下链接了解为什么我们应该将 @Transaction 放在服务层。
    “@Transactional”应该放在哪里服务层或DAO
  2. 您不应该在服务层处理异常。原因:由于服务层为DB操作执行多个DAO,如果任何DAO失败,我们需要回滚事务。如果我们在服务中处理异常,那么我们可能不会回滚事务。回滚事务有手动方法,但不推荐。TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

So handle transaction in controller layer.

所以在控制器层处理事务。

回答by beerbajay

You don't handle exceptions at all levels of your application simultaneously; you have to consider their contextual meaning and what the appropriate strategy is for your application. Some errors should be ignored, some should be wrapped, some should be allowed to be raised directly.

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

One method for dealing with exceptions in a spring-mvcapplication is to wrap fatal errors from the underlying libraries with your own where appropriate, named for the level at which they are thrown, e.g. ServiceExceptionor RepositoryException. A @ControllerAdvice-annotated class can then handle these errors with @ErrorHandler-annotated methods and return 5XXhttp errors.

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

Common application errors, like an entity not being found due to an incorrect idcan result in a custom exception, e.g. NotFoundExceptionbeing raised and subsequently caught in your @ControllerAdvice-annotated class.

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

The advantage to this technique is that you have less error-handling code in your different application layers and can centralize the conversion of exceptions to responses.

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

An example @ControllerAdvice-annotated class:

一个带@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);
    }
}