vc tem algum component factory que pode retornar null?
o guice não gosta disso por padrão, então se sim vc precisa anotar essa dependência como @Nullable no PrivilegioInterceptor
Rafael_Guerreiro
Ixi… Muitas pelo sistema todo… Existe alguma forma de tirar isso em um lugar só?
Lucas_Cavalcanti
vc recebe várias dependências que podem ser null?
isso geralmente não é muito legal, já que te obriga a ficar fazendo if (x != null) pelo sistema inteiro…
tem um padrão (design pattern) chamado Null Object que pode te ajudar
Rafael_Guerreiro
Na verdade existe algumas coisas que eu devo fazer quando for nulo…
Então com esse Null Object eu retorno uma nova instância ao invés de retornar nulo?
Lucas_Cavalcanti
isso, uma instância que se comporta como se fosse uma instancia normal, mas retorna os valores que vc usaria com os if (x != null)
e vc ainda poderia fazer algo do tipo:
publicclassBanjo{publicstaticfinalBanjoNULL=newBanjo();}...if(banjo==Banjo.NULL){//lógica do null}
Lucas_Cavalcanti
em todo caso, a idéia do padrão não é mudar o if null pra if NULL, e sim evitar esses ifs
Rafael_Guerreiro
De qual pacote é o @Nullable?
Consegui resolver com a ideia de uma “instância nula”…
Como que eu faria depois quanto às SessionFactories com relação ao @SessionScoped?
eu criei o meu CustomProvider, como você disse no outro tópico. Só que ao contrário de SessionFactory, eu quero retornar Session, cada uma da respectiva SF.
Porém, como eu faço para receber neste provider uma SF anotada cm @Component e @SessionScoped? Pois eu queria usar a mesma SF por sessão…
Lucas_Cavalcanti
abrir uma SF por sessão de usuário geralmente é bem caro… é isso mesmo que vc quer fazer? O ideal é ter uma SF por base de dados, e só.
o @Nullable é do guice (com.google.algumacoisa)
como está o código do seu provider?
os métodos anotados com @Provides podem receber dependências como parametro, e serem anotados com escopo:
Entendi, então os métodos anotados com @Provides funcionam como as classes anotadas com @Component.
Meu CustomProvider:
packagebr.com.wsacervoweb.implementations;importjavax.inject.Named;importorg.hibernate.Session;importbr.com.caelum.vraptor.ioc.guice.GuiceProvider;importcom.google.inject.AbstractModule;importcom.google.inject.Module;importcom.google.inject.Provides;publicclassCustomProviderextendsGuiceProvider{staticclassCustomModuleextendsAbstractModule{privatefinalModulemodule;CustomModule(Modulemodule){this.module=module;}@Overrideprotectedvoidconfigure(){install(this.module);// configurations}@ProvidespublicSessiongetSession(){// cria a session do banco da empresareturnnull;}@Provides@Named("WSAcervoWeb")publicSessiongetSessionWSAcervoWeb(){// cria a session do banco da warriorsoftreturnnull;}}@OverrideprotectedModulecustomModule(){returnnewCustomModule(super.customModule());}}
O @Nullable que eu tenho é da Sun... Por isso não funcionou... Acho que eu não tenho esse jar do guice.
A ideia é que eu tenha uma SessionFactory que seja @ApplicationScoped e outra que seja @SessionScoped...
Deve ser assim pois cada empresa acessa um banco de dados diferente.
-Edit-
Aqui diz que a anotação @SessionScoped não pode ser usada em métodos...
Estou usando o @Named de javax.injection mas eu tenho um outro aqui que é do google...
Lucas_Cavalcanti
tenta fazer diferente então. Ao invés do @Provides, tente um @Component assim:
anote os construtores dos providers com @Inject (vc tá usando a api direta do guice, em que a injeção pelo construtor não é automática)
Rafael_Guerreiro
Arrumei isso, ai eu vi um erro em relação aos Sessions, mudei o pacote( de org.hibernate.classic.Session para org.hibernate.Session, não sei bem a diferença) e ficou somente esse erro:
1) No implementation for org.hibernate.SessionFactory annotated with @com.google.inject.name.Named(value=SessionFactoryWSAcervoWeb) was bound.
while locating org.hibernate.SessionFactory annotated with @com.google.inject.name.Named(value=SessionFactoryWSAcervoWeb)
for parameter 0 at br.com.wsacervoweb.implementations.SessionWSAcervoWebProvider.<init>(SessionWSAcervoWebProvider.java:20)
at br.com.wsacervoweb.implementations.CustomProvider$CustomModule.configure(CustomProvider.java:29)
Lucas_Cavalcanti
troque o @Named(“SessionFactoryWSAcervoWeb”) por @Named(“WSAcervoWeb”) (foi assim que vc configurou no module)
Rafael_Guerreiro
Mas, na verdade, eu tenho dois casos. Um é o da session (“WSAcervoWeb”) e o outro é o da SessionFactory dessa session (“SessionFactoryWSAcervoWeb”)…
Eu devo anotar TODOS os construtores que recebem dependência com @Inject?
-Edit-
¬¬’
Agora eu vi o que vc quis dizer…
Arrumei, mas aí ele voltou a dar erro de objeto nulo…
1) null returned by binding at br.com.wsacervoweb.implementations.CustomProvider$CustomModule.configure(CustomProvider.java:24)
but parameter 0 of br.com.wsacervoweb.implementations.SessionProvider.<init>() is not @Nullable
while locating br.com.wsacervoweb.implementations.SessionFactoryProvider
while locating org.hibernate.SessionFactory
for parameter 0 at br.com.wsacervoweb.implementations.SessionProvider.<init>(SessionProvider.java:18)
at br.com.wsacervoweb.implementations.SessionProvider.class(SessionProvider.java:1)
while locating br.com.wsacervoweb.implementations.SessionProvider
while locating org.hibernate.Session
for parameter 4 at br.com.wsacervoweb.controller.MainController.<init>(MainController.java:46)
at br.com.caelum.vraptor.ioc.guice.GuiceComponentRegistry.bindToConstructor(GuiceComponentRegistry.java:110)
while locating br.com.wsacervoweb.controller.MainController
então vc tem que usar @Named(“WSAcervoWeb”) SessionFactory factory. Não tem problema usar o mesmo nome, desde que sejam classes/interfaces diferentes.
não são todos os construtores, são só os dos componentes que vc configurou direto no guice (com o module). Os do vraptor vão continuar do mesmo jeito que antes
Rafael_Guerreiro
É eu vi, entao eu editei a mensagem anterior.
Arrumei, mas aí ele voltou a dar erro de objeto nulo…
1) null returned by binding at br.com.wsacervoweb.implementations.CustomProvider$CustomModule.configure(CustomProvider.java:24)
but parameter 0 of br.com.wsacervoweb.implementations.SessionProvider.<init>() is not @Nullable
while locating br.com.wsacervoweb.implementations.SessionFactoryProvider
while locating org.hibernate.SessionFactory
for parameter 0 at br.com.wsacervoweb.implementations.SessionProvider.<init>(SessionProvider.java:18)
at br.com.wsacervoweb.implementations.SessionProvider.class(SessionProvider.java:1)
while locating br.com.wsacervoweb.implementations.SessionProvider
while locating org.hibernate.Session
for parameter 4 at br.com.wsacervoweb.controller.MainController.<init>(MainController.java:46)
at br.com.caelum.vraptor.ioc.guice.GuiceComponentRegistry.bindToConstructor(GuiceComponentRegistry.java:110)
while locating br.com.wsacervoweb.controller.MainController
Lucas_Cavalcanti
talvez se vc criar uma anotação @Nullable funcione
Rafael_Guerreiro
Criei a annotation Nullable e então o sistema funciona certinho.
Mas agora vem o problema:
A SessionFactory que não tem o @Named só pode ser criada depois que a pessoa fizer o login…
Pois eu só consigo construir essa SessionFactory depois de saber os dados da empresa da pessoa…
Não tenho a mínima ideia de como fazer isso…
vc pode fazer um provider que recebe as informações do usuário, e cria a sf de acordo com ele
Rafael_Guerreiro
Como que seria esse provider? Mas ele teria que ser executado depois q a pessoa fizer o login…
Lucas_Cavalcanti
o mesmo provider que vc já criou…
só que lá dentro em algum lugar vc faz:
if(sf==null&&usuarioestálogado){
sf=criasf
}
só que dai ele potencialmente vai retornar null no get
Rafael_Guerreiro
Eu posso receber parâmetros no CustomProvider? Ele é executado o tempo todo?
Lucas_Cavalcanti
o provider que eu to falando é o SessionFactoryWSAcervoWebProvider ou coisa do tipo…
se não for o cara anotado, vc pode criar um ComponentFactory e fazer a lógica lá
Rafael_Guerreiro
Ahh! Isso eu já faço, só que o problema é que ele é @SessionScoped, entao ele fica retornando null para sempre…
Lucas_Cavalcanti
não entendo pq ele fica null sempre…
vc tá recebendo as informações de usuário nessa classe?
vc tá fazendo o if maroto dentro do getInstance()? (o getInstance é chamado toda hora)
Rafael_Guerreiro
Não, ele fica no construtor… Se uma hora ele mudar a classe que contém as informações sobre o usuário, lá vai mudar também? (Sem que seja preciso receber de novo?)
Lucas_Cavalcanti
vc pode ficar fazendo a verificação sempre no getInstance ao invés de no construtor… aí vc consegue trocar as informações
Rafael_Guerreiro
Consegui resolver o problema, dessa forma como você disse…
Eu tinha me confundido e colocado o @Named em um lugar onde a session deveria ser a padrão…