em uma classe DAO não gerenciada pelo container JEE, que no meu caso é Glassfish (3.1.1b12). Isso é possivel usando um DAO Stateless, mas sabemos que não é uma boa prática.
Alguém conseguiu realizar essa Injeção, usando Glassfish, num DAO Not-Stateless? Vi alguns relatos de alguns que conseguiram em JBoss.
Nesse caso ele faz lookup por JNDI no Datasource configurado no meu Glassfish para atribuir à field da Classe.
Eu fiz isso diretamente no meu persistence.xml, ao injetar um @PersistenceContext, ja vai o EntityManager gerenciado pelo Glassfish na configuração do pool de conexao. Sem necessidade de fazer lookup no codigo.
E tem como fazer com que uma classe “comum” se torne gerenciada pelo Container? Vi alguma coisa a respeito configurando beans.xml, ou estou enganado?
Sei que realmente usar os DAOs como Stateless é má prática(pool de instancia, etc), mas se tratando de integração EJB x JPA, será que não seria uma opção?
obrigado.
G
garcia-jj
Não existe uma classe comum ser gerenciada: ou ela é “comum” ou ela é gerenciada. O beans.xml serve apenas para “ativar” o CDI no projeto. Para uma classe ser gerenciada basta ser um EJB ou uma classe anotada com as annotations do CDI. Lembrando que uma classe gerenciada você NUNCA deve fazer new, e sim sempre pedir uma instância ao container.
Sobre DAO ser um EJB Stateless… isso você leu lá no meu post no Stackoverflow, né? Na verdade a discução surgiu após algumas pesquisas minhas. Eu sempre usei os meus DAOs e repositórios como EJB Stateless, mas quando surgiu o CDI surgiram várias idéias de usar beans do CDI ao invés de EJB, o que faz um pouco de sentido. Abri então a discução no Stackoverflow mas as opiniões foram bem divididas. Fiz uns testes aqui e não notei diferença alguma, já que beans do CDI são muito semelhantes a um Local Bean do EJB.
Lá no meu post que você achou no Stackoverflow tem o exemplo do que uso hoje. Aquele bug que reportei lá é um problema do Glassfish 3.0. Isso não acontece mais no Glassfish 3.1+ e nem no JBoss 6+.
L
lucasmurata
garcia-jj:
Não existe uma classe comum ser gerenciada: ou ela é “comum” ou ela é gerenciada. O beans.xml serve apenas para “ativar” o CDI no projeto. Para uma classe ser gerenciada basta ser um EJB ou uma classe anotada com as annotations do CDI. Lembrando que uma classe gerenciada você NUNCA deve fazer new, e sim sempre pedir uma instância ao container.
Sobre DAO ser um EJB Stateless… isso você leu lá no meu post no Stackoverflow, né? Na verdade a discução surgiu após algumas pesquisas minhas. Eu sempre usei os meus DAOs e repositórios como EJB Stateless, mas quando surgiu o CDI surgiram várias idéias de usar beans do CDI ao invés de EJB, o que faz um pouco de sentido. Abri então a discução no Stackoverflow mas as opiniões foram bem divididas. Fiz uns testes aqui e não notei diferença alguma, já que beans do CDI são muito semelhantes a um Local Bean do EJB.
Lá no meu post que você achou no Stackoverflow tem o exemplo do que uso hoje. Aquele bug que reportei lá é um problema do Glassfish 3.0. Isso não acontece mais no Glassfish 3.1+ e nem no JBoss 6+.
Cara, muito bacana.
Eu acho que se integrar esse recurso de CDI com Vraptor (como foi citado em outro tópico) vai ser um negocio sensacional.
Quanto à discussão EJB Stateless ou CDI pra DAO, acho que daria uma discussão muito legal, será que o pessoal ta afim?
Olhei o seu código no stack, estou testando do jeito que está la aqui so que recebi um null pointer no EntityManager. Faltei configurar algo?
Na verdade eu tenho usado um mix de EJB e CDI com sucesso. Minhas classes repositórios são beans do CDI e na camada de negócio tenho EJBs, que recebem esses repositórios via @Inject. E na camada web VRaptor fazendo lookup local dos EJBs.
@Repository
public class UserRepository {
@PersistenceContext
private EntityManager entityManager;
}
@Dependent
@Stereotype
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Repository {
}
Na verdade eu tenho usado um mix de EJB e CDI com sucesso. Minhas classes repositórios são beans do CDI e na camada de negócio tenho EJBs, que recebem esses repositórios via @Inject. E na camada web VRaptor fazendo lookup local dos EJBs.
@Repository
public class UserRepository {
@PersistenceContext
private EntityManager entityManager;
}
@Dependent
@Stereotype
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Repository {
}
É mais ou menos assim que eu uso.
Muito legal, parabéns.
Só uma duvida:
garcia-jj:
O beans.xml serve apenas para “ativar” o CDI no projeto.
Nesse seu exmplo, preciso colocar alguma coisa no beans.xml? Estou recebendo null no EntityManager.
Valeu!
G
garcia-jj
O beans.xml pode ser vazio. Não tem porque dar NullPointerException.
Como está teu código?
L
lucasmurata
garcia-jj:
O beans.xml pode ser vazio. Não tem porque dar NullPointerException.
Como está teu código?
Eu segui seu exemplo mas eu devo estar fazendo algo errado,
Eu injetei o mesmo PersistenceContext no Servlet, e deu certo.
G
garcia-jj
Se o @Component que você está tentando usar é do VRaptor, esquece. Não é assim que funciona. Injetar coisas do container só funciona em beans gerenciados pelo container.
L
lucasmurata
É, realmente era isso mesmo. Seria bom demais se conseguisse. Mas ok.
Parabéns pelas suas iniciaivas.
Abraço!.
G
garcia-jj
Já tinhamos conversado no tópico sobre VRaptor, e eu já tinha te dito isso.
Se você quer injetar o EntityManager, porque você não injeta o do VRaptor?
Se você precisa realmente de um Entity Manager gerenciado, use EJB ou CDI na camada de serviço, e use o Service Locator que te passei naquele tópico.
L
leosrbrasil
Não sei se é isso que vc quer, mas consegui criar/acessar instancias gerenciadas de fora do cdi.
Minha motivação foi pegar uma Session gerenciada do hibernate dentro de um listener (como uso Tomcat a injeção não funciona nos listeners).
Taí meu código:
O BeanManagerLocator é do Seam Solder, mas se vc arrumar um jeito de pegar o BeanManager de outra forma nem precisa dele. Assim no meu listener só precisei fazer :
Não sei se é isso que vc quer, mas consegui criar/acessar instancias gerenciadas de fora do cdi.
Minha motivação foi pegar uma Session gerenciada do hibernate dentro de um listener (como uso Tomcat a injeção não funciona nos listeners).
Taí meu código:
O BeanManagerLocator é do Seam Solder, mas se vc arrumar um jeito de pegar o BeanManager de outra forma nem precisa dele. Assim no meu listener só precisei fazer :