在@Stateless bean中注入时@Inject失败

时间:2016-05-29 16:32:39

标签: java dependency-injection ejb cdi

我正在使用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为空。

为什么注射点失效?我在这里错过了什么?

为了进行一些测试,我通过在OperationRepository构造函数中实例化默认MenuRepository来手动注入,但在这种情况下,OperationRepository.entityManager未注入(为空)< / p>

提前感谢您的回答。

编辑#1

根据John Ament的要求,请点击此处:

  1. 我的所有代码都在一个jar文件中。它是一个Maven模块,将与 Glassfish Server 4.1 中的Web模块(war包)一起部署。
  2. beans.xml仍然不存在,因为项目尚未准备好部署(我还没有进行任何集成测试)
  3. MenuRepository来自@Test课程,因为我还在开发MenuRepository
  4. 测试类的代码如下:

    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();
        }
    }
    

    我认为这就是我到目前为止所做的一切。让我知道你可以得到(或猜测)的任何线索

1 个答案:

答案 0 :(得分:1)

因为您正在测试CDI容器,所以您还应该在测试类的@Before方法中手动设置依赖项。

menuRepository.setOperationRepository(operationRepository)