EJB无状态会话bean中的CDI bean生成器

时间:2014-02-21 11:01:13

标签: java java-ee design-patterns ejb cdi

假设我有一个名为db-utils的简单库,它有一个CrudService CDI bean(requestScoped),我的Web应用程序使用它来执行CRUD操作。

我还有一个名为grad-db的EJB项目,它有从数据库映射的实体。 Grad-db还有用于在db-utils的CrudService中设置entityManager的生产者。

我已经尝试过,显然它工作正常。我的问题是:这是一种不好的做法吗?是否在无状态会话bean中生成CDI bean并将EJB无状态bean作为参数传递给CrudService有什么后果?

我的代码:

EJB Bean(grad-db):

@Stateless
public class CrudServiceCae extends AbstractCrud implements Serializable {
    private static final long serialVersionUID = 1L;

    @PersistenceContext(unitName = "cae-pu")
    EntityManager em;

    @Override
    public EntityManager getEntityManager() {
        return em;
    }

    @Produces
    @Database(Schema.CAE)
    public CrudService createCrudServiceCou() {
        return new CrudService(this);
    }
}

CrudService(db-utils):

@Named("crudService")
public class CrudService implements Serializable {

    private static final long serialVersionUID = -2607003150201349553L;

    private AbstractCrud crud;

    public CrudService(AbstractCrud abstractCrud) {
        this.crud = abstractCrud;
    }

    ...
}

修改 实际上它只适用于查询。当我尝试插入数据时,我得到了javax.persistence.TransactionRequiredException。显然,在这种情况下我将不得不使用继承而不是CDI。

1 个答案:

答案 0 :(得分:1)

EJB负责业务流程/逻辑(即:方法),并且能够协调其他CDI控制器,让EJB创建对象并不常见,因为您更喜欢CDI POJO Producer。

在你的情况下更精简地使用CDI对象并从那里生成你需要的对象,看起来像DAO并且可以用于(我的意思是,注入)到EJB中。

使用专用控制器来考虑边界模式的EJB。

注意:

  • @Stateless不需要实现Serializable,这些是池化的,它的生命周期不允许序列化。
  • 一般情况下,您不希望将getter用于EJB的实体管理器,您应该更喜欢编写方法并在内部使用em
  • 如果使用JTA
  • ,持久化上下文更容易操作
  • 你的@Stateless应该开始交易并让它们沿控制器传播
  • 具有包可见性的em是一个好主意,让您轻松模拟您的立面/边界