注入@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 的要求,这里是:

  1. 我所有的代码都在一个 jar 文件中。它是一个 Maven 模块,将与 Web 模块(war 包)一起部署在 Glassfish Server 4.1.
  2. beans.xml 仍然不存在,因为项目还没有准备好部署(我还没有执行任何集成测试)
  3. 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)