Spring / JPA / JSF的异常处理策略 [英] Exception Handling Strategy with Spring/JPA/JSF

查看:187
本文介绍了Spring / JPA / JSF的异常处理策略的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们在我们的应用程序中使用JSF,Spring和JPA。我们正在尝试简化我们项目的异常处理策略。



我们的应用程序架构如下所示:



UI(JSF) - >管理Bean - >服务 - > DAO



我们正在使用异常翻译bean后处理器进行DAO层。这是在Spring应用程序上下文文件中配置的。

 < bean class =org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor > 

其中Spring将所有数据库异常包装到org.springframework.dao.DataAccessException。我们没有在DAO层中执行任何其他异常处理。



我们处理例外情况的策略如下:



演示文稿层

  Class PresentationManangedBean {

try {
serviceMethod();
} catch(BusinessException be){
//映射在UI上显示的异常消息
}
catch(异常e){
//映射异常消息以显示在UI
}

}

服务层

  @Component(service)
班级服务{

@Transactional(propagation = Propagation.REQUIRED,readOnly = false,rollbackFor = BusinessException.class)
public serviceMethod(){

try {

daoMethod();

} catch(DataAccessException cdae){
抛出新的BusinessException(); //我们的业务/自定义异常
}
catch(异常e){
抛出新的BusinessException(); //我们的业务/自定义例外
}
}

}

DAO图层

  @Repository(dao)
类DAO {

public daoMethod(){
//没有异常被处理
//如果发生任何DataAccessException或RuntimeException,这个
//被抛出到ServiceLayer
}

}

问题:
我们只想确认上述方法是否符合最佳做法。如果没有,请建议我们处理例外情况(使用交易管理)的最佳方法?

解决方案

我使用其他方法:



- 我没有在DAO中捕捉到Spring的DAE。我让他们流到Controller(JSF管理的bean)。



- 在控制器中,我捕获任何异常(只有一个catch)。



- 我调用一个自定义的handleException方法,它接收参数中捕获的异常。



- 这个异常处理程序检查例如,使用if-then-else语句)参数是什么样的异常,并根据这种异常向用户显示消息。在我的情况下,我寻找消息显示在属性文件中,消息的键(和args如果有的话)是异常的属性(我把它放在那里,当我抛出它)。特别是,如果要以特殊的方式处理DAE,可以在此异常处理程序方法中添加一个if分支,并且可以随意使用它。



我认为这种方法是更好和更干净的,因为你只需要一点处理异常处理,并且你不必在每个级别都放置这么多的throws-try-catch,就在Controller(JSF) )



当然,您可以在服务中使用try-catch来获取特定的异常,如果在这种特定情况下想要做的是一些业务逻辑,向用户显示一条消息。



而且,如果您不想在控制器中处理Spring DAE,则可以将其包装成一个业务异常你自己和重投但是在服务层,而不是在DAO中。



希望这个答案有帮助。


We are using JSF, Spring and JPA in our application. We are trying to simplify our Exception Handling strategy for our project.

Our application architecture is like below:

UI(JSF) --> Managed Beans --> Service --> DAO

We are using Exception Translation bean post processor for DAO layer. This is configured in Spring Application Context file.

<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" /> 

Where Spring wraps all database exceptions to 'org.springframework.dao.DataAccessException'. We are not doing any other exception handling in DAO Layer.

Our strategy to handle exceptions like below:

Presentation Layer:

Class PresentationManangedBean{

 try{
      serviceMethod();
   }catch(BusinessException be){
      // Mapping exception messages to show on UI
   }
   catch(Exception e){
       // Mapping exception messages to show on UI
   }

}

Service Layer

@Component("service")
Class Service{

 @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = BusinessException.class)
 public serviceMethod(){

  try{

      daoMethod();

   }catch(DataAccessException cdae){
      throws new BusinessException(); // Our Business/Custom exception
   }
   catch(Exception e){
      throws new BusinessException();  //  Our Business/Custom exception
   }
 }

}

DAO Layer

@Repository("dao")
Class DAO{

 public daoMethod(){
  // No exception is handled
  // If any DataAccessException or RuntimeException is occurred this 
  // is thrown to ServiceLayer
 }

}

Question: We just want to confirm whether above approach is as per the best practices. If not, please suggest us the best way to handle the exceptions (playing with transaction management)?

解决方案

I use a different approach:

-I don't catch the DAE of Spring in the DAO. I let them flow up to the Controller (JSF managed bean).

-In the controller I catch any Exception (with just one "catch").

-I call a custom "handleException" method which receives the Exception caught in a parameter.

-This exception handler checks (for example,with an "if-then-else" sentence) what kind of exception is the parameter, and shows the message to the user according to that kind of exception. In my case I look for the message to show in a properties file, where the key (and the args if any) of the message are attributes of the exception (I put them there when I throw it). In particular, if you want to handle DAE in a special way, you can put an "if" branch for it in this exception handler method, and do whatever you want with it.

I think this approach is better and cleaner, because you have the exception handling in just one point, and you don't have to put so much "throws-try-catch" in every level, just in the Controller (JSF).

Of course, you can use "try-catch" in services for particular exceptions, if what you want to do in that particular case is some business logic, instead of showing a message to the user.

And also, if you don't want to deal with Spring DAE in the controller, you can wrap it into a business exception of your own and re-throw. But do this in the service layer, not in DAO.

Hope this answer helps.

这篇关于Spring / JPA / JSF的异常处理策略的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆