【问题标题】:why do I get an EJBTransactionRolledbackException when I call two DAOs in my EJB Service?为什么在我的 EJB 服务中调用两个 DAO 时会收到 EJBTransactionRolledbackException?
【发布时间】:2012-03-01 14:44:17
【问题描述】:

我正在使用 IBM RAD 7.5 和 WebSphere 7。

我有一个 EJB (@Stateless CustomerService),还有两个 EJB 是 DAO(@Stateless CustomerDAO 和 @Stateless OrderDAO)。

当我执行 customerDAO.getAll() 时,我在 CustomerService 中的方法工作正常。

但如果我调用 customerDAO.getAll() 然后 orderDAO.getByCustomerId(int id),第二个 getAll 会抛出 EJBTransactionRolledBackException。

为什么会发生这种情况,如何预防?

谢谢,罗伯

用代码更新

我有这个...

@Stateless
public class CustomerService
  @EJB
  private CustomerDAO customerDAO;
  @EJB
  private OrderDAO orderDAO;

  public void myMethod() {
    List<Customer> customers = customerDAO.getAll();
    for (Customer c : customers) {
      List<Order> orders = orderDAO.getByCustomerId(c.getId());
      /*** THIS THROWS EJBTransactionRolledBackException ***/
    }
  }

...我的 DAO 看起来像这样...

@Stateless
public class CustomerDAO
  @PersistenceUnit
  private EntityManagerFactory emf;

  public EntityManager getEntityManager() {
    return emf.createEntityManager();
  }

  public List<Customer> getAll() {
    try {
      em = getEntityManager();
      Query query = em.createQuery(" /*...*/ ");
      query.getResultList();
    } finally {
      em.close();
    }
  } 

...和...

@Stateless
public class OrderDAO
  @PersistenceUnit
  private EntityManagerFactory emf;

  public EntityManager getEntityManager() {
    return emf.createEntityManager();
  }

  public List<Customer> getByCustomerId(int customerid) {
    try {
      em = getEntityManager();
      Query query = em.createQuery(" /*...*/ ");
      /* ... */
      query.getResultList();
    } finally {
      em.close();
    }
  } 

有什么想法吗?

谢谢,罗伯

【问题讨论】:

    标签: java ejb


    【解决方案1】:

    我猜您的 EJB 事务分界存在问题。首先,您的 DAO 不应该是 EJB。 EJB 应该用于服务层,其中主要优势之一是声明性事务管理。通过使您的 DAO 成为 EJB,您可以在 DAO 方法级别参与容器管理的事务操作。

    如果您提供您的 dao 代码和配置,我们可以做出更明确的评估。

    【讨论】:

    • 谢谢。目前,DAO 是 EJB,服务通过 @EJB 注释获得一个引用。如果 DAO 不是 EJB,我应该只在 EJB 代码中执行 MyDAO dao = new MyDAO 吗?谢谢!
    • 取决于您的 DAO 的配置方式(例如,您如何获取数据库连接的句柄等),或者您使用的是 Spring?
    • 嗨——我在我的问题中添加了示例代码(上图)。另外,我查看了我拥有的几个示例(在线和书中),并且两者都将“DAO”标记为@Stateles,所以我认为这合适吗?
    • 你在哪里实例化你的 DAO 中的 EntityManager (em)?
    • 是的,在 DAO 中。我在上面的代码示例中添加了“getEntityManager”方法。谢谢!
    猜你喜欢
    • 2017-09-25
    • 1970-01-01
    • 2019-06-28
    • 1970-01-01
    • 1970-01-01
    • 2016-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多