2013-04-22 144 views
1

我有3层的EJB:处理JPA交易异常

第一种是持久性:

@Stateless 
@TransactionAttribute(TransactionAttributeType.REQUIRED) 
public class PersistenceService 
{ 
    @PersistenceContext(unitName="pc") 
    EntityManager em; 

    public <T> void create(T entity) { 
     em.persist(entity); 
    } 
} 

第二个是业务:

@Stateless 
@TransactionAttribute(TransactionAttributeType.REQUIRED) 
public class BusinessService implements 
{ 
    @EJB 
    PersistenceService persistenceService; 

    public <T> void register (User user) { 
      try{ 
        // Do some business 
        persistenceService.persist(user); 
        // Do other business 
      }catch(Exception e){ 
        // log exception 
        throw new BusinessException(e); 
      } 
     } 
} 

第三个是一个Web调用业务EJB的服务。

问题是,业务EJB不捕获数据库异常,例如封装在EJB异常中的Mysql连接器抛出的约束违反异常。我可以在Rest服务EJB上处理这个异常,但不能在业务EJB上处理。我认为这与交易有关。

我不确定哪些事务属性应该添加到持久性EJB和业务EJB中,以让我在业务EJB中捕获这些类型的异常。

+0

为什么不能在业务层处理异常?你有没有看到任何异常? – 2013-04-23 05:23:53

+0

,因为异常发生在业务方法范围之外的事务中。 – mmohab 2013-04-23 14:23:46

回答

0

你是对的,显示的行为可能与交易界限有关。您的Web服务(我现在正在猜测)是上层的非EJB层,因此当您调用BusinessService.register()时,事务就在调用之前开始,并在该调用返回之前结束。

运行时异常发生在提交时,您的情况发生在register()方法的代码结束之后;因此在那里处理它们为时尚早。

你有两个选择,如果你真的不想处理的Web服务的bean例外:

一个。使用豆在BusinessService

@Stateless 
@TransactionManagement(TransactionManagementType.BEAN) 
public class BusinessService 
{ 
@EJB 
PersistenceService persistenceService; 
@Resource 
private UserTransaction ut; 

public <T> void register (User user) { 
     try{ 
       ut.begin(); 
       // Do some business 
       persistenceService.persist(user); 
       // Do other business 
       ut.commit(); 
     }catch(Exception e){ 
       // log exception 
       throw new BusinessException(e); 
     } 
    } 
} 

两个管理的事务。在Web服务bean和EJB之间引入非事务外观:

@Stateless 
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) 
public FacadeBean { 

    @EJB private BusinessService businessService; 

    public void facadeMethod(User user) { 
     try { 
      businessService.register(user); 
     } 
     // your handling code here 
     catch (...) { ... } 
    } 

} 
+0

感谢分享:),认为非事务层更好,因为我仍然喜欢容器管理事务。 – mmohab 2013-04-23 14:14:23