Ainda não tem acesso? Estude com a gente! Matricule-se
Ainda não tem acesso? Estude com a gente! Matricule-se

Solucionado (ver solução)

Dependência de CDI e Negociacao serializable

No console vejo a mensagem: CDI @ViewScoped bean functionality unavailable

O estranho é que mesmo com esse warning a anotação de @ViewScoped funciona como esperado - o objeto é construído apenas ao carregar a página, sendo mantido na navegação entre suas páginas e nas reordenações, como confirmei colocando um sysout no construtor.

Pesquisando no Google vi que acrescentando no POM a dependência do cdi-api a mensagem desaparece - só não entendi o que muda na prática.

Além disso, vi que o Serializable não é requisito para o @View Scoped funcionar - só que ao parar e reiniciar o servidor aparecem mensagens reclamando que Negociacoes não é serializable. Além disso, para essas mensagens desaparecerem por completo, Negociacao também precisa declarar que implementa a interface, senão aparecem mensagens dizendo que a mesma não é serializable.

6 respostas

Fala Leonardo, tudo bem?

Eu acredito que tenha que adicionar a dependência no maven pra que ele pegue os .jar da dependência e não do servidor. Ele funciona sem colocar no POM provavelmente porque está pegando os jars do servidor.

Quanto ao serializable, para manter o seu objeto por mais de um request, que é o caso do ViewScoped, precisa implementar Serializable, assim ele consegue salvar o objeto em binário e guardar por mais tempo.

Espero ter ajudado =)

O Serializable provavelmente ajuda na hora de reiniciar o servidor e manter as sessões, ou talvez em um cluster de servidores onde uma session possa ser dinamicamente transferida - mas como verifiquei nos meus testes a ausência dele não impede que o @ViewScoped funcione - o objeto é inicialzado apenas uma vez.

Oi Leonardo, desculpe a demora para responder.

Como foi o teste que vc realizou?

Abraço

Tirei o Serializable das classes Negociacoes e Negociacao, deixei o @ViewScoped, e coloquei um sysout no construtor do Bean - a aplicação (depois de recompilada e do servidor restartado, claro) teve o comportamento esperado do @ViewScoped - o construtor somente era chamado ao carregar a view - a simples troca de paginação não chamava o construtor.

Leonardo, dei uma olhada aqui na documentação e lá pede que o o Bean seja serializable.

Segue o link, caso queira dar uma olhada: http://docs.oracle.com/javaee/7/api/javax/faces/view/ViewScoped.html

O trecho que ele diz isso é: "Use of this annotation requires that any beans stored in view scope must be serializable and proxyable as defined in the CDI specification." ou em tradução livre, "O uso dessa anotação requer que qualquer bean guardado no View Scoped precise ser Serializable e proxyable como definido na especificação do CDI".

O que ocorre é que dependendo do servido ele já serializa o objeto pra você, existem também algumas configurações no web.xml que mudam essa necessidade de implementar a interface Serializable. Um JSON ou uma entidade do hibernate são todos serializaveis mas não precisa implementar a interface Serializable.

O teste que você fez de colocar um sysout no servidor não mostra muita coisa, além de quando o objeto foi instanciado. O objeto só vai ser desserializado quando o servido precisar, ou seja no seu teste você precisaria forçar o servidor a precisar do objeto que está serializado.

solução

Acho que não deixei claro, mas o objetivo do sysout no construtor não era testar a serialização ou desserialização - o objetivo era testar se o objetivo da anotação @ViewScoped era alcançado - ou seja, que o objeto não ia ser re-instanciado enquanto o usuário estivesse acessando aquela View - independentemente da classe declarar que implementa Serializable ou não.

E isso ficou claro nos testes - sem a declaração de Serializable, o @ViewScoped faz com o que o objeto seja instanciado apenas ao carregar a página. Retirando o @ViewScoped, o objeto é instanciado (e printando no console a cada vez que o construtor é chamado) a cada vez que se troca a página atual.

De qualquer forma não estou defendendo não fazer a declaração - acho péssima idéia - não vejo vantagem nenhuma em não declarar na classe que ela é Serializable, até porque ela realmente já implementa a interface (se não fosse o caso daria o erro ao inserir a declaração). Apenas queria registrar um comportamento que achei interessante do @ViewScoped, que é não depender (pelos meus testes) da declaração de Serializable - apesar da ausência da declaração causar problemas, como as mensagens de erro atestam.