Search code examples
javadependency-injectionejbcdi

@Inject failing when injecting in a @Stateless bean


I'm working in a project with Java EE 7 and I need to inject a javax.ejb.@Stateless bean into another. Both beans have a similar structure:

@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
    }
}

The GenericRepository<E> is just an abstract class with some common methods and other abstract methods, doesn't matter here.

The problem is that in the getMenuFromOperation() method I get a NullPointerException. Debugging the code I realized that the injected operationRepository is null when requested in the method.

Why does fail the injection point? what am I missing here?

Just to make a little test, I injected manually by instantiating a default OperationRepository in the MenuRepository constructor, but in that case the OperationRepository.entityManager isn't injected (is null)

Thanks in advance for your answers.

Edit #1

As requested by John Ament, here it goes:

  1. All my code is in a single jar file. It's a Maven module that will be deployed together with a web module (a war package) in a Glassfish Server 4.1.
  2. The beans.xml still doesn't exists yet, because the project isn't ready to be deployed (I didn't perform any integration test yet)
  3. The MenuRepository is leveraged from a @Test class because I'm still developing MenuRepository.

The code for the test class is as follows:

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
    }
}

And the BaseTestRepository is as follows:

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

I think that's all I got so far. Let me know any clue you can get (or guess)


Solution

  • Because you're testing out of the CDI container you should also set your dependencies manually in the @Before method of the test class.

    menuRepository.setOperationRepository(operationRepository)