1

I have a common generic DAO in common lib. I want in each module which uses this DAO to initialize with its own persistence UNIT

public abstract class GenericDao implements IGenericDao {

@PersistenceContext(unitName = "XXXX")
private EntityManager entityManager;

and in other module

public class CarDao extends GenericDao{

I have lot of projects are using this generic DAO but each project have its own persistence unit.

Persitence unit are differents following the project where is used the common library

The point is i could not use POO with abstract getEntityManager injected in each micro servicies because in common project we have a history DAO common for all microservicies and for each one i have to retrieve the entityManager injected from the microservice

Am i doing wrong or well? and how set th epersistence unit in each project ? (each project have lot fo DAO and i don't want repet each time CRUD methods)

cyril
  • 872
  • 6
  • 29

2 Answers2

1
@PersistenceContext(unitName = "XXXX")
private EntityManager entityManager;

This should be done in each concrete class, the abstract one should implement the concrete operation using

getEntityManager().doSomething(entity)

the getter getEntityManager() being abstract.

Imho this is a design smell, EntityManager is already an abstraction and you have nothing to gain encapsulating it.

[edit]

Regarding the "factory" approach, the way in CDI to dynamically inject resources is using producer methods.

You can so create a method returning an EntityManager instance that will dynamically resolve the EntityManagerFactory according to the persistence unit name (see an example here).

Note that this is a very bad idea as the entityManager scope is usually bound to the transaction one, letting the container inject you the entityManager instance guarantee that the scope will be correctly handled (by the container). The only viable configuration with this approach is when you want an "application managed" entityManager

NB: note that the given example will instantiate a new EntityManageFactory instance for each injection which can be really catastrophic according to the way you use it (the EntityManageFactory should be created once for all the application)

be sure to be aware of EntityManager lifecycle before going further.

Gab
  • 7,869
  • 4
  • 37
  • 68
  • thanks i will test it but if i have 30 DAO i have to inject 30x the entity manager !! in each class.... maybe with a factory or something like that i could achieve it – cyril Mar 25 '19 at 13:40
  • the problem is i have in this common library an Audit DAO used for each module... and will use the entitymanager defined for each project, as the method will be abstract i will need define to in this class but how ? because it ihnerit from the generic – cyril Mar 25 '19 at 14:02
  • Ok thank you it is working i have only one problem, i have in my common lib a DAO for Audit it will be used by all project so, it have to use the EntityManager for each project, as the genericDAO method getENtityManager is generic, how in my audit i can retrieve the current entityManager (it is made in post update so we are sure that entityManager have been already injected) – cyril Mar 26 '19 at 11:55
  • Guy, this is basic OOP polymorphism... getEntityManager is abstract so the concrete invocated method will be the one of your specialized instance. If the answer is working please accept it. Anyway if you use producer method keep it mind that the entityManager instance is not thread safe and should be created for each transaction (each http request in a web context) – Gab Mar 26 '19 at 13:19
  • i think you miss something in my common project i have a historyDAO used in all microservicies... it will use the entityManager injected in microservice so, i can not use abbstract getEntitymanager because how i do in the historyDao in common project where is the generic DAO ? – cyril Apr 01 '19 at 13:26
0

Thank you guy for your advices in fact i was totally stupid in my genericDao i simply put

public abstract class GenericDao implements IGenericDao {


@PersistenceContext
private EntityManager entityManager; 

As we have only one PersistentUnit it will be automatically injected....

was so easy !

then i can use @PersistentContext in all DAOs or simply and best call getEntityManager from their parent IGenericDao

cyril
  • 872
  • 6
  • 29