注入@Stateless bean 时@Inject 失败
@Inject failing when injecting in a @Stateless bean
我在一个使用 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>
只是一个抽象class,有一些常用方法和其他抽象方法,这里无所谓。
问题是在 getMenuFromOperation()
方法中我得到了 NullPointerException。调试代码我意识到在方法中请求时注入的 operationRepository
为 null。
为什么注入点会失败?我在这里错过了什么?
只是为了做一个小测试,我通过在 MenuRepository
构造函数中实例化一个默认的 OperationRepository
来手动注入,但在那种情况下 OperationRepository.entityManager
没有被注入(是 null )
提前感谢您的回答。
编辑#1
根据 John Ament 的要求,这里是:
- 我所有的代码都在一个
jar
文件中。它是一个 Maven 模块,将与 Web 模块(war
包)一起部署在 Glassfish Server 4.1. 中
beans.xml
仍然不存在,因为项目还没有准备好部署(我还没有执行任何集成测试)
MenuRepository
是 @Test
class 的杠杆,因为我仍在开发 MenuRepository
。
测试class的代码如下:
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();
}
}
我想这就是我到目前为止所得到的。让我知道你能得到(或猜测)的任何线索
因为您是在 CDI 容器外进行测试,所以您还应该在测试的 @Before
方法中手动设置依赖项 class。
menuRepository.setOperationRepository(operationRepository)
我在一个使用 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>
只是一个抽象class,有一些常用方法和其他抽象方法,这里无所谓。
问题是在 getMenuFromOperation()
方法中我得到了 NullPointerException。调试代码我意识到在方法中请求时注入的 operationRepository
为 null。
为什么注入点会失败?我在这里错过了什么?
只是为了做一个小测试,我通过在 MenuRepository
构造函数中实例化一个默认的 OperationRepository
来手动注入,但在那种情况下 OperationRepository.entityManager
没有被注入(是 null )
提前感谢您的回答。
编辑#1
根据 John Ament 的要求,这里是:
- 我所有的代码都在一个
jar
文件中。它是一个 Maven 模块,将与 Web 模块(war
包)一起部署在 Glassfish Server 4.1. 中
beans.xml
仍然不存在,因为项目还没有准备好部署(我还没有执行任何集成测试)MenuRepository
是@Test
class 的杠杆,因为我仍在开发MenuRepository
。
测试class的代码如下:
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();
}
}
我想这就是我到目前为止所得到的。让我知道你能得到(或猜测)的任何线索
因为您是在 CDI 容器外进行测试,所以您还应该在测试的 @Before
方法中手动设置依赖项 class。
menuRepository.setOperationRepository(operationRepository)