【发布时间】:2016-05-29 16:32:38
【问题描述】:
我正在使用 Java EE 7 进行项目,我需要将 javax.ejb.@Stateless bean 注入到另一个项目中。两个 bean 具有相似的结构:
@Stateless
public class OperationRepository extends GenericRepository<Operation> {
@PersistenceContext
private EntityManager entityManager;
public OperationRepository() {
}
/*Implementation of abstract methods, getters/setters, etc*/
}
@Stateless
public class MenuRepository extends GenericRepository<Menu> {
@PersistenceContext
private EntityManager entityManager;
@Inject
private OperationRepository operationRepository;
public MenuRepository() {
}
/*idem OperationRepository*/
public List<Menu> getMenuFromOperation(...) {
// Do something where I need operationRepository
}
}
GenericRepository<E>只是一个抽象类,有一些常用方法和其他抽象方法,这里无所谓。
问题是在getMenuFromOperation() 方法中我得到一个NullPointerException。调试代码发现注入的operationRepository在方法中请求时为null。
为什么注入点失败?我在这里错过了什么?
只是为了做一个小测试,我通过在 MenuRepository 构造函数中实例化默认的 OperationRepository 手动注入,但在这种情况下 OperationRepository.entityManager 没有注入(为空)
提前感谢您的回答。
编辑#1
根据John Ament 的要求,如下:
- 我所有的代码都在一个
jar文件中。这是一个 Maven 模块,将与一个 Web 模块(war包)一起部署在 Glassfish Server 4.1 中。 -
beans.xml仍然不存在,因为该项目尚未准备好部署(我尚未执行任何集成测试) -
MenuRepository来自@Test类,因为我仍在开发MenuRepository。
测试类的代码如下:
public class MenuOperationRepositoryUTest extends BaseTestRepository {
private MenuRepository menuRepository;
private OperationRepository operationRepository;
@Before
public void initTestCase() {
initTestDB();
menuRepository = new MenuRepository();
menuRepository.setEntityManager(em);
operationRepository = new OperationRepository();
operationRepository.setEntityManager(em);
}
@After
public void finalizeTestCase() {
closeEntityManager();
}
/*Some successful tests*/
@Test
public void showMenuFromOperation() {
// Insert some dummy data into the test DB (HSQL)
// This method needs the injected OperationRepository in MenuRepository
List<Menu> menu = menuRepository.getMenuFromOperation(...);
// Assertions
}
}
而BaseTestRepository如下:
@Ignore
public class BaseTestRepository {
private EntityManagerFactory emf;
protected EntityManager em;
// This is a helper class that contains all the boilerplate to begin transaction
// and commit, it's used to insert data in the test DB
protected DBCommandExecutor dbCommandExecutor;
protected void initTestDB() {
// sigeaPU is the name declared in persistence.xml
emf = Persistence.createEntityManagerFactory("sigeaPU");
em = emf.createEntityManager();
dbCommandExecutor = new DBCommandExecutor(em);
}
protected void closeEntityManager() {
em.close();
emf.close();
}
}
我想这就是我目前所得到的一切。让我知道你能得到(或猜测)的任何线索
【问题讨论】:
-
按接口创建接口和
@Inject。 -
@Geinmachi,据我了解,当 bean 是本地的时,您可以省略接口。我还看到其他项目使用相同的结构,我认为情况并非如此。如果您需要有关该项目如何解决另一个可能的问题的更多信息,请告诉我。
-
您能否分享利用
MenuRepository的代码?您能否也分享一下您的包装结构。这一切都在一个战争中吗?您要部署到什么容器?你的beans.xml是什么样的? -
...In an implicit archive, CDI can only manage and inject beans annotated with a scope type. For a web application, the beans.xml deployment descriptor, if present, must be in the WEB-INF directory.您的无状态 EJB 上没有范围类型。你应该把 beans.xml 放在你的 jar 和 war 中。 -
在这种情况下,您在哪里遇到空引用问题并不清楚。在您的测试用例中,我没有看到将 OperationRepository 手动设置到 MenuOperationRepository 中,如果您不这样做就不会发生奇迹(对吗?)。
标签: java dependency-injection ejb cdi