DAO+EntityManager Injetado+ Projeto Separado que Herda deste DAO

5 respostas
S

Srs,

Estou com a seguinte dúvida/problema:

Tenho um GenericDAO em um Projeto e este DAO é um Stateless, ele possuí um EntityManager injetado

@PersistenceContext(unitName = "SuprimentosG3PU") public EntityManager em;

Em outro projeto e outro DAO (RequisicaoDAO) faço um extends neste DAO.
Ao fazer o Deploy o JBOSS informa o seguinte erro:

Can't find a persistence unit named 'SuprimentosG3PU' in AbstractVFSDeploymentContext@19555183{vfs:///C:/jboss/server/default/apps/SuprimentosServer.jar}

Se coloco o mesmo persistence.xml no segundo projeto o JBoss informa:

Caused by: java.lang.IllegalStateException: persistence.unit:unitName=#SuprimentosG3PU is already installed.

É possível fazer isto? Ou a Arquitetura está incorreta?

Preciso muito da ajuda de vocês,

Obrigado pessoal!!

5 Respostas

dev.rafael

Pq vc tem um DAO genérico que injeta um EntityManager se o EntityManager é um DAO genérico???

S

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")
})
public class User implements Serializable {
  private static final long serialVersionUID = 1L;

  public static final String ALL = "User.all";
...

e então:

// in some EJB...
@PersistenceContext EntityManager em;
...
public void doSomethingThatNeedsAllUsers() {
  // something before...
  List<User> users = em.createNamedQuery(User.ALL);
  // another thing after...
}

Ou seja, EntityManager é ou não é um DAO genérico?

S

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
@Entity
public class Person {
  // código...
}

// DAO
@Stateless
@TransactionAttribute(REQUIRED)
public class PersonDAO {
  @PersistenceContext EntityManager em;

  // código ...

  // Um novo método para cada query.
  public List<Person> findPeopleByName(String name) {
    return em.createQuery("select p from Person p where p.name like :name").setParameter("name", "%" + name + "%").getResultList();
  }

  // código ...
}

@Named
public class TestBean {
  // Uso ...
  @EJB PersonDAO dao;

  public List<Person> getPeople() {
    return dao.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")
})
public class Person {
  public static final String BY_NAME = "Person.byName";

  // código
}

// Uso
@Named
public class TestBean {
  @PersistenceContext EntityManager em;

  public List<Person> getPeople() {
    return em.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.

Criado 23 de agosto de 2010
Ultima resposta 24 de ago. de 2010
Respostas 5
Participantes 2