DAO Factory

102 views
Skip to first unread message

Carlos Eduardo Serpa

unread,
Sep 19, 2011, 9:34:49 AM9/19/11
to javasf
Olá todos ... estou usando um DAO generico onde o injeto usando uma fabrica
-->Fábrica
@Stateless
public class DAOFactory{   
    @PersistenceContext(name="SEIAPU")
    EntityManager entityManager;
   
    @Produces
    public DAO createDAO(InjectionPoint injectionPoint) throws Exception {
        ParameterizedType type = (ParameterizedType) injectionPoint.getType();
        Class classe = (Class) type.getActualTypeArguments()[0];
        return new DAO(classe, entityManager);   
    }   
}

--> Dao Genérico
public class DAO<T> implements Serializable{
    private Class<T> entityClass;
    private EntityManager entityManager;

    public DAO(Class<T> entityClass, EntityManager entityManager) {
        this.entityClass = entityClass;  
        this.entityManager =entityManager;
    }
   
    public DAO(Class<T> entityClass) {
        this.entityClass = entityClass;       
    }
   
    protected EntityManager getEntityManager(){
        return this.entityManager;
    };

    public void create(T entity) {
        getEntityManager().persist(entity);
    }
....
}

Só que em determinada situação vou precisar especializar o Dao genérico tipo... O usuário terá uma ação no banco não definida no DAo Generico tipo:

public class UsuarioDAO extends DAO<Usuario> {   
    public UsuarioDAO() {
        super(Usuario.class);
    } 
       
    public String visivel(){ /// --> esse método não fica vísivel para mim
        return null;
    }  
 
}


essa é chamada:
@Inject
    private DAO<Modelo> modeloDao;  

o método vísivel não está disponível para mim, mas ele está herdando de DAO, a fábrica está me retornando uma instância do Pai, por isso não posso ver o método no filho, é isso ? como posso resolver ?
Ou deveria usar named query específico nos entitys(Nesse caso Usuario), ou criar um metodo genérico no DAO para tratar com Criterias(que não é bonito no JPA) ?


--
My best regards
Carlos Eduardo Serpa de Sousa
Systems Analyst
Sun Certified Programmer for Java 2 Platform, Standard Edition 5.0 - SCJP

Henrique Pereira de Souza

unread,
Sep 19, 2011, 9:43:37 AM9/19/11
to jav...@googlegroups.com
Carlos, tenta fazer assim :
 
@Inject
private UsuarioDAO usuarioDAO;
 
pois assim você estará injetando o DAO de usuário especifico e não o genérico.

--
Você recebeu esta mensagem por que é membro do Javasf
http://groups.google.com/group/javasf
 
Conheça também o Java Brazil: http://groups.google.com/group/thejavabrazil

Carlos Eduardo Serpa

unread,
Sep 19, 2011, 9:56:04 AM9/19/11
to jav...@googlegroups.com
@Henrique

Dessa forma que estou usando, mas aí não perderia o proposito da fábrica? Queria saber se era possível a fabrica me retornar o objeto especializado se preciso ...

@Inject
DAO<Usuario> usuarioDAO;

2011/9/19 Henrique Pereira de Souza <henrique....@gmail.com>

Douglas Ramiro

unread,
Sep 19, 2011, 9:59:28 AM9/19/11
to jav...@googlegroups.com
Cara, o problema está nos conceitos de orientação a objeto. O que você quer é impossível de implementar.

Quando vc define como tipo uma classe abstrata ou uma interface, você só terá acesso ao métodos definidos pela mesma. Porém será executado a implementação da instância.
Douglas Ramiro
_____________________________________
Java Developer
Sun Certified Java Associate (SCJA)
Sun Certified Java Programmer (SCJP)

Henrique Pereira de Souza

unread,
Sep 19, 2011, 10:04:15 AM9/19/11
to jav...@googlegroups.com
Na verdade o objetivo do DAOFactory é retornar o DAO génerico com a classe preenchida, pois o servidor ou container não sabe por si só qual classe retornar, no seu caso que foi preciso criar um DAO especifico está é a forma mais correta, so mais uma dica aqui no serviço não extedemos o DAO génerico fazemos desta forma:
 
@Inject
private DAO<Usuario> usuarioDAO;
 
@Inject
 private UsuarioDAO usuarioDAO;

 Assim diminui o acoplamento, desta forma que aprendi no curso da caelum.

Kenji

unread,
Sep 19, 2011, 10:21:15 AM9/19/11
to jav...@googlegroups.com
o que é a injeção senão outra forma de factory?

[]

Kenji

Carlos Eduardo Serpa

unread,
Sep 19, 2011, 10:42:57 AM9/19/11
to jav...@googlegroups.com
@Henrique...

Entao no caso do
@Inject
 private UsuarioDAO usuarioDAO;

você rescreveria todos os metodos que estaria no DAO genérico já que não os herdam mais, é isso ?

ou se precisar do genério, usando duas referencias ??
@Inject
private DAO<Usuario> usuarioDAO;

e se for preciso algo específico :
@Inject
 private UsuarioDAO usuarioDAO;



Henrique Pereira de Souza

unread,
Sep 19, 2011, 10:45:41 AM9/19/11
to jav...@googlegroups.com
No caso aqui a gente usa as duas referências:
 
@Inject
private DAO<Usuario> usuarioDAOGenerico;

e se for preciso algo específico :
@Inject
 private UsuarioDAO usuarioDAO;



vagner coelho pinto

unread,
Sep 19, 2011, 2:17:38 PM9/19/11
to jav...@googlegroups.com
Mas galera,

O correto não seria o seu objeto especialista ter tudo que o generico tem mas o especifico dele?

como trabalhar com duas referencias para o mesmo objeto, perdi um pouco o sentido não?

Eu uso da seguinte forma:
 
public class Dao<T> {

@In("entityManager")
protected EntityManager em;

@SuppressWarnings("unchecked")
private Class classe;
private Session session;

@SuppressWarnings("unchecked")
public Dao(Class classe) {
this.classe = classe;
this.em = (EntityManager) Component.getInstance("entityManager");
}

public void save(T obj) {
session = (Session) em.getDelegate();
session.save(obj);
}

public void delete(T obj) {
session = (Session) em.getDelegate();
session.delete(obj);
}
}
@Name("daoFactory")
public class DaoFactory {

public DaoFactory() {
super();
}
public Dao<UsuarioSistema> getUsuarioSistema(){
return new Dao<UsuarioSistema>(UsuarioSistema.class);
}

public ItemFluxoPapelDao getItemFluxoPapelDao() {
return new ItemFluxoPapelDao();
}
}
Quando recupero do meu factory ja tenho o obejto que preciso ele é que sabe o que é especialista ou não, faço somente a injeção do factory.

Espero ter ajudado.

Douglas Ramiro

unread,
Sep 19, 2011, 2:35:37 PM9/19/11
to jav...@googlegroups.com
Sim... Exatamente. Mas tem um detalhe, o que determina o comportamenteo do seu objeto é o que está a esquerda do = ou seja

Dao<Usuario> dao = new UsuarioDao();

significa que o tipo do seu objeto é o genérico mas que a implementação que a máquina virtual vai executar é a de UsuarioDao. Isso faz muito sentido afinal observe o exemplo a seguir

public class Animal {
   public void dormir(){ ... }
}

public class Cachorro extends Animal{
   public void latir() { ... }
}

public class Gato extends Animal{
  public void miar(){ ... }
}

Animal a = new Cachorro();

você pode fazer tranquilamente a.dormir();

mas como a máquina virtual iria se comportar com a.miar() sendo que o seu objeto é um cachorro?  Um cachorro jamais vai miar. Por isso que apenas o método dormir poderá ser executado. Afinal tanto cachorro quanto gato dormem. Essa é a ideia de generalização. Você identifica apenas o que é comum.
Reply all
Reply to author
Forward
0 new messages