0

I know i can do the following :

public class MyDao{

  private EntityManager em;

  public void setEm(EntityManager em){
     this.em = em;
  }
  ...

and then, using @PostConstuct to pass the EntityManager

public class MyBean{
  private EntityManager em;

  @Inject
  private MyDao myDao;

  @PostConstruct
  private void init(){
    myDao.setEm(em);
  }
...

But due to my application's architecture restriction i cannot directly inject MyDao into MyBean, i should pass by MyBusinessDao Class, so i tried the following but i'm getting a nullPointerExeception on the value of EntityManager in MyDao :

    public class MyBean{

    private EntityManager em;

    public MyBean(){
        em = createEntityManager();
    }

    private EntityManager createEntityManager(){
        //dynamically create the EntityManager
    }

    @Inject
    private MyBusinessDao myBusinessDao;

    @PostConstruct
    private void init(){
       myBusinessDao.setEm(em);
    }
   ...

and in MyBusinessDao i inject MyDao:

 public class MyBusinessDao {

    private EntityManager em;

    @Inject
    private MyDao myDao;

    @PostConstruct
    private void init(){
      myDao.setEm(em);
    }
    ...

I should mention that i'm not using a J2EE container

Hen
  • 253
  • 1
  • 2
  • 16
  • Just declare the em where you actually need it, and annotate it with `@PersistenceContext`. Why would you inject it where you don't need it and then try to pass it to other beans? – JB Nizet Mar 28 '19 at 19:51
  • @JBNizet thanks for answering, in fact all the (business, doa and entities) classes will be packaged in a jar and used in by another team who will provide their own entityManager so that's why it should be declared at a higher level – Hen Mar 28 '19 at 19:58
  • 3
    No, it shouldn't. Beans are beans. – JB Nizet Mar 28 '19 at 20:02
  • Can you suggest me another way to pass the `EntityManager` from my Bean to the Dao – Hen Mar 28 '19 at 20:07
  • 1
    As I said, just don't. Inject it where you need it. The DAO is a bean, which lives in the application where an EntityManager is available, and the EM will thus be injected in the DAO. – JB Nizet Mar 28 '19 at 20:12
  • If the other team uses an own EntityManager they will have a Producer for this. So you can simply inject the EntityManager where you need it as @JBNizet already said. – Marcel Goldammer Mar 29 '19 at 08:55
  • @MarcelGoldammer the `EntityManager` will be dynamically created so we cannot use a producer – Hen Mar 29 '19 at 09:33
  • If you are not using a container how do you think that @PostConstruct should work? – Simon Martinelli Mar 29 '19 at 09:41
  • How does this dynamically creation work without a Producer method? – Marcel Goldammer Mar 29 '19 at 09:42
  • @SimonMartinelli i'm using `Weld` to resolve injections and annotaitons – Hen Mar 29 '19 at 09:44
  • And where do you produce the EntityManger. It's not injected in your code – Simon Martinelli Mar 29 '19 at 09:46
  • @SimonMartinelli the `EntityManager` will be created at runtime as it's shown here https://stackoverflow.com/a/42372648/4663461 – Hen Mar 29 '19 at 09:47
  • But then you should create a producer method and then inject it in MyBusinessDao or how do you think that the entity manger will find it's way to MyBusinessDao? – Simon Martinelli Mar 29 '19 at 09:49
  • @SimonMartinelli can you see my edit please! – Hen Mar 29 '19 at 10:23
  • But you do myBusinessDao.setEm(em); and then you have also and init method where you set em? – Simon Martinelli Mar 29 '19 at 10:25
  • @SimonMartinelli what i'm trying to do is : create the `EntityManager` in MyBean then pass it as parameter to myBusinessDao which should also pass it to myDao, because i cannot inject myDao directly into MyBean – Hen Mar 29 '19 at 10:30
  • And why do you think that you can't inject it? When you can call a method you can also inject it – Simon Martinelli Mar 29 '19 at 10:41
  • @SimonMartinelli thanks for the help, i solved it by using the `@PostConstuct` only in MyBean and then in the setEm of MyBusinessDao i called setEm of MyDao – Hen Mar 29 '19 at 10:48
  • So Please post this as answer – Simon Martinelli Mar 29 '19 at 12:05

2 Answers2

2

You can implement an CDI Producer Method for providing the EntityManager via CDI injection.

@ApplicationScoped
class EntityManagerProducer {

   @PersistenceContext(...)
   private EntityManager em;

   @Produces
   @RequestScoped
   public EntityManager produceEm() {
      return em;
   }
}

You can also inject the EntityManagerFactory and call emf.createEntityManager() in the producer method and implement an CDI-Disposer method, which closes the EntityManager before the scope is finished.

public void dispose(@Disposes EntityManager em) { ... }

If you have multiple persistence contexts, then implement a producer method for each persistence context and qualify them with a CDI-Qualifier.

Thomas Herzog
  • 506
  • 2
  • 6
  • i cannot use producer because the `EntityManager` is being created at runtime – Hen Mar 31 '19 at 13:13
  • 1
    No, problem, then make the during runtime created em available via an producer. The CDI producer just makes types and their instances available to CDI in the defined scope for the defined qualifier (@Default per default), nothing more. – Thomas Herzog Mar 31 '19 at 13:23
-2

I resolved it this way :

public class MyBusinessDao {

    private EntityManager em;

    @Inject
    private MyDao myDao;

    private void setEm(EntityManager em){
    this.em = em;
    //and here i call the setEm method of myDao also
    myDao.setEm(em);
    }
    ...
Hen
  • 253
  • 1
  • 2
  • 16
  • 1
    I think the problem a fellow community member has with your solution is that you on the hand use CDI for providing dependencies on the other hand you use getter/setter to provide dependencies as well. This is a mixup I wouldn't recommend, because your are coupled to the beans where you need to provide the dependencies. Each time a new bean is implemented, you need to ensure to implement to set the EntityManager. With CDI injection you only define your dependency and CDI will take care of providing it. The beauty of CDI is being completely decoupled from bean creation and bean provisioning. – Thomas Herzog Apr 03 '19 at 06:10