3

我有一个 web 模块和一个 ejb 模块打包到一个 EAR 中。

我有 JSF 支持 bean 成功地从 ejb 模块注入会话 EJB,这些模块能够从数据库中提取数据,例如

@RequestScoped
public class CarController {

    @EJB
    private CarService carService;

为了支持 Primefaces LazyDataModel,会话 EJB 将其 EntityManager 暴露给 LazyDataModel:

@PostConstruct
public void init() {
    MyLazyDataModel<Car> myLazyDataModel = new MyLazyDataModel<Car>();
    myLazyDataModel.setEntityManager(carService.getEntityManager());
    super.setMyLazyDataModel(myLazyDataModel);
}

这会导致以下异常:

java.lang.IllegalStateException: Unable to retrieve EntityManagerFactory for unitName null
at    com.sun.enterprise.container.common.impl.EntityManagerWrapper.init(EntityManagerWrapper.java:132)
at    com.sun.enterprise.container.common.impl.EntityManagerWrapper._getDelegate(EntityManagerWrapper.java:173)
at   com.sun.enterprise.container.common.impl.EntityManagerWrapper.getCriteriaBuilder(EntityManagerWrapper.java:895)
at com.cars.web.controller.MyLazyDataModel.load(MyLazyDataModel.java:154)
at org.primefaces.component.datatable.DataTable.loadLazyData(DataTable.java:731)

这是否不起作用,因为 PersistenceContext 只是在 ejb 模块中传递的有效 bean?

4

1 回答 1

0

出于资源和/或 EJB 注入的目的,使用 JSF bean 或 CDI bean 是等效的。

我会避免在同一应用程序中以两种不同的方式(即通过 PersistenceContext 注入和通过 EntityManagerFactory)检索 EntityManager。特别是 EntityManagerFactory 实例化是一个重量级操作。

如果你做MyLazyDataModel一个匿名内部类,那就容易多了,因为你可以直接使用注入的DAO服务,不需要直接在bean中处理EntityManager。你可以在这个答案中看到一个具体的例子。

与具体问题无关,最适合惰性数据表的 bean 范围似乎至少是 ViewScoped(仅适用于 jsf bean)。

于 2013-06-25T07:09:39.190 回答