Pq vc tem um DAO genérico que injeta um EntityManager se o EntityManager é um DAO genérico???
S
Santinho
Tenho diversos métodos que estarão disponíveis em todos os DAO’s de minha aplicação, e estes métodos utilizam o EntityManager para algumas funções.
Não é comum ter esta abordagem?
GenericDAO
|//------------------------------> Esta linha divide o Projeto 1 (Libs) do Projeto 2 (Suprimentos)
|---ExemploDAO
|---Exemplo2DAO
|---Exemplo3DAO
Tenho que ter o EntityManager em cada um dos DAOs?
dev.rafael
Kra, é importante q vc se preocupe em reaproveitar esse tipo de código mas é importante lembrar de alguns pontos.
Primeiro, herança é p/ polimorfismo e ñ p/ reaproveitamento de código. P/ reaproveitar código vc usa composição.
Segundo:
@Entity@NamedQueries({@NamedQuery(name=User.ALL,query="select u from User u")})publicclassUserimplementsSerializable{privatestaticfinallongserialVersionUID=1L;publicstaticfinalStringALL="User.all";...
e então:
// in some EJB...@PersistenceContextEntityManagerem;...publicvoiddoSomethingThatNeedsAllUsers(){// something before...List<User>users=em.createNamedQuery(User.ALL);// another thing after...}
Ou seja, EntityManager é ou não é um DAO genérico?
S
Santinho
Ele pode até ser considerado um DAO Genérico por conseguir fazer diversas operações com qualquer Entity.
Mas é comum sim se utilizar de um DAO Genérico que possuem métodos que serão utilizados em todos os DAO’s (vide Livro Java Persistence com Hibernate).
E eu tenho métodos que são utilizados e chamados quando o objeto é um DAO (não importando qual seja), utilizando Herança em sua correta finalidade e não apenas para re-aproveitar código.
Acontece que se faço extends deste DAO em outro projeto ele diz que não encontra o SuprimentosG3PU.
O que fiz por hora foi mudar a maneira de injetar o EntityManager, agora o Deploy funcionou porém não tive tempo de testar (Mudança de prioridades).
Obrigado!
dev.rafael
Adam Bien; Real World Java EE Patterns Rethinking Best Practices
Agora uma comparação prática:
DAO:
// Entity@EntitypublicclassPerson{// código...}// DAO@Stateless@TransactionAttribute(REQUIRED)publicclassPersonDAO{@PersistenceContextEntityManagerem;// código ...// Um novo método para cada query.publicList<Person>findPeopleByName(Stringname){returnem.createQuery("select p from Person p where p.name like :name").setParameter("name","%"+name+"%").getResultList();}// código ...}@NamedpublicclassTestBean{// Uso ...@EJBPersonDAOdao;publicList<Person>getPeople(){returndao.findPeopleByName(name);}}
Named queries:
// Sua entidade@Entity@NamedQueries({// Uma nova anotação p/ cada query.@NamedQuery(name=Person.BY_NAME,query="select p from Person p where p.name like :name")})publicclassPerson{publicstaticfinalStringBY_NAME="Person.byName";// código}// Uso@NamedpublicclassTestBean{@PersistenceContextEntityManagerem;publicList<Person>getPeople(){returnem.createNamedQuery(Person.BY_NAME).setParameter("%"+name+"%").getResultList();}}
O uso das NamedQueries não é apenas mais econômico em termos de linhas de código como também traz a vantagem de que
suas queries serão checadas no momento da implementação da aplicação enquanto q queries convencionais (no meio do código)
são checadas em runtime. E ainda contém bem menos boilerplate code pois vc não terá que criar uma nova classe DAO para cada
entidade que for criada no seu sistema.