Estou trabalhando e um novo projeto e surgiu a oportunidade de utilizar CDI e estou com um problema.
Na classe abaixo utilizo um factory method para retornar uma entidade e gostaria de usar CDI para injetar o repositório, porém eu obtenho uma NullPointerException na linha novoCopo.repositorio.persistir(novoCopo);
Aparentemente se eu crio uma classe ele não faz a injeção de dependência! Já testei o código e a injeção funciona se eu não crio a classe! Se alguém tiver alguma ideia de como fazer isso agradeço!
[code]public class Copo {
… @Inject@Transient
private Repositorio repositorio;
public static Copo novo(String nome, int volume){
Copo novoCopo = new Copo();
novoCopo.setNome(nome);
novoCopo.setVolume(volume);
novoCopo.repositorio.persistir(novoCopo);
return novoCopo;
}
Para o CDI funcionar o Copo instanciado tem que ser gerenciado/instanciado pelo Weld ou injetor de depência que esteja utilizando.
Você está fazendo apenas uma instância simples do Copo (“new Copo()”).
Isso deve funcionar:
@ManagedBean
public class CopoBean {
@Inject
private Repositorio<Copo> repositorio;
public Copo salvar(String nome, int volume) {
Copo copo = new Copo();
copo.setNome(nome);
copo.setNome(volume);
repositorio.persistir(copo);
return copo;
}
}
Repare que não é você que instância o ManagedBean, ou servlet, ou etc, quem cria essa instância é que é responsável pela instaciação dos seus atributos (injeção de dependência), seja CDI, Spring, Guice, etc.
O problema é que o modo como copo é criado no seu código é através de new, ou seja, ele não é gerenciado pelo weld, logo não recebe injeção, portanto o fluxo da sua aplicação deve se arquitetado de tal forma que copo seja injetado e não criado manualmente.
Um exemplo seria a injeção de um objeto do tipo Instance<Copo> para produzir novas instancias do objeto gerenciadas.
Te recomendou ma boa leitura na documentação do weld, é muito completa.
[quote=cleciusjm]O problema é que o modo como copo é criado no seu código é através de new, ou seja, ele não é gerenciado pelo weld, logo não recebe injeção, portanto o fluxo da sua aplicação deve se arquitetado de tal forma que copo seja injetado e não criado manualmente.
Um exemplo seria a injeção de um objeto do tipo Instance<Copo> para produzir novas instancias do objeto gerenciadas.
Te recomendou ma boa leitura na documentação do weld, é muito completa.[/quote]
Já dei uma olhada na documentação do Weld mas não achei nada para isso, encontrei algo no Guice, onde tem uma injeção estática
Isso na classe que usa a classe copo, ou seja, dessa forma voce consegue ter o seu @Inject do repository dentro da classe copo.
Quem irá utilizar o copo deve ser gerenciado pelo weld e ter a injeção do Instance<Copo>.
[quote=cleciusjm]Isso na classe que usa a classe copo, ou seja, dessa forma voce consegue ter o seu @Inject do repository dentro da classe copo.
Quem irá utilizar o copo deve ser gerenciado pelo weld e ter a injeção do Instance<Copo>.[/quote]
Só que a classe Copo é criada pela própria classe copo através de um Factory Method e esse é justamente o problema! Se o copo fosse injetado não haveria problema, bem como se fosse usado um DAO ao invés de um repositório!
[code]public class Copo {
… @Inject@Transient
private Repositorio<Copo> repositorio;
public static Copo novo(String nome, int volume){
Copo novoCopo = new Copo();
novoCopo.setNome(nome);
novoCopo.setVolume(volume);
novoCopo.repositorio.persistir(novoCopo);
return novoCopo;
}
[quote=x@ndy][quote=cleciusjm]Isso na classe que usa a classe copo, ou seja, dessa forma voce consegue ter o seu @Inject do repository dentro da classe copo.
Quem irá utilizar o copo deve ser gerenciado pelo weld e ter a injeção do Instance<Copo>.[/quote]
Só que a classe Copo é criada pela própria classe copo através de um Factory Method e esse é justamente o problema! Se o copo fosse injetado não haveria problema, bem como se fosse usado um DAO ao invés de um repositório!
[code]public class Copo {
… @Inject@Transient
private Repositorio<Copo> repositorio;
public static Copo novo(String nome, int volume){
Copo novoCopo = new Copo();
novoCopo.setNome(nome);
novoCopo.setVolume(volume);
novoCopo.repositorio.persistir(novoCopo);
return novoCopo;
}
…
}[/code][/quote]
Quem vai usar o Copo? Quem for instanciar o copo pode ter um Instance<Copo>…
[quote=cleciusjm]
Quem vai usar o Copo? Quem for instanciar o copo pode ter um Instance<Copo>…[/quote]
Então eu poderia fazer simplesmente @Inject Copo!
O problema é que assim eu obtenho uma instancia do objeto em um estado inconsistente o que não é minha ideia! A Fabrica tem a função justamente de devolver um objeto totalmente consistente!
[quote=x@ndy][quote=cleciusjm]
Quem vai usar o Copo? Quem for instanciar o copo pode ter um Instance<Copo>…[/quote]
Então eu poderia fazer simplesmente @Inject Copo!
O problema é que assim eu obtenho uma instancia do objeto em um estado inconsistente o que não é minha ideia! A Fabrica tem a função justamente de devolver um objeto totalmente consistente![/quote]
Vai na documentação do Java EE6 e leia sobre o que é um método produtor, anotado com @Produces… 99% de chance de resolver o seu problema.
[quote=diegosammet][quote=x@ndy][quote=cleciusjm]
Quem vai usar o Copo? Quem for instanciar o copo pode ter um Instance<Copo>…[/quote]
Então eu poderia fazer simplesmente @Inject Copo!
O problema é que assim eu obtenho uma instancia do objeto em um estado inconsistente o que não é minha ideia! A Fabrica tem a função justamente de devolver um objeto totalmente consistente![/quote]
Vai na documentação do Java EE6 e leia sobre o que é um método produtor, anotado com @Produces… 99% de chance de resolver o seu problema.[/quote]
O problema não é o método produtor. De uma olhada na questão inicial!
[quote=x@ndy][quote=diegosammet][quote=x@ndy][quote=cleciusjm]
Quem vai usar o Copo? Quem for instanciar o copo pode ter um Instance<Copo>…[/quote]
Então eu poderia fazer simplesmente @Inject Copo!
O problema é que assim eu obtenho uma instancia do objeto em um estado inconsistente o que não é minha ideia! A Fabrica tem a função justamente de devolver um objeto totalmente consistente![/quote]
Vai na documentação do Java EE6 e leia sobre o que é um método produtor, anotado com @Produces… 99% de chance de resolver o seu problema.[/quote]
O problema não é o método produtor. De uma olhada na questão inicial![/quote]
Na realidade, o método produtor lhe permitiria criar um estado consistente pra esse objeto.
[quote=cleciusjm][quote=x@ndy][quote=diegosammet][quote=x@ndy][quote=cleciusjm]
Quem vai usar o Copo? Quem for instanciar o copo pode ter um Instance<Copo>…[/quote]
Então eu poderia fazer simplesmente @Inject Copo!
O problema é que assim eu obtenho uma instancia do objeto em um estado inconsistente o que não é minha ideia! A Fabrica tem a função justamente de devolver um objeto totalmente consistente![/quote]
Vai na documentação do Java EE6 e leia sobre o que é um método produtor, anotado com @Produces… 99% de chance de resolver o seu problema.[/quote]
O problema não é o método produtor. De uma olhada na questão inicial![/quote]
Na realidade, o método produtor lhe permitiria criar um estado consistente pra esse objeto.
[/quote]
Exato, se ele tivesse pelo menos lido essa parte da especificação teria entendido o que eu disse.
[quote=diegosammet][quote=cleciusjm]
Na realidade, o método produtor lhe permitiria criar um estado consistente pra esse objeto.
[/quote]
Exato, se ele tivesse pelo menos lido essa parte da especificação teria entendido o que eu disse.[/quote]
cleciusjm e diegosammet, pelo que eu li na documentação o produtor é chamado pelo container para criar um objeto e depois injeta-lo! O produtor funciona como uma fabrica, permitindo que um objeto mais complexo seja criado bem como devido o escopo desse objeto!
Pegando o meu exemplo, tenho um objeto Copo e dentro dele existe um objeto Repositorio que necessita ser injetado! O objeto Repositorio tem um produtor pois alem de ser genérico ele tambem necessita de um EntityManager que passado para ele durante a construção!
Se eu injetar o objeto Copo tudo funciona perfeitamente! Até o colega dobau deu um exemplo! Só que isso não é o que eu quero pois minha entidade é criada em um estado inconsistente!
A meu ver um produtor para o copo não resolve o problema pois necessito passar parâmetros para ele de modo que eu tenho que cria-lo ao invés de injeta-lo. Os parâmetros só estarão disponíveis em runtime isso é um cadastro. Posso receber esses dados de diferentes fontes de modo que não são parâmetros injetados que possam ser usados por um produtor!
Bom, conforme vocês eu estou errado e existe uma forma de passar esses parâmetros de modo que posso usar um método produtor então peço aos dois que por favor me esclareçam como posso fazer!