[RESOLVIDO] ViewScoped managed bean não está sendo recriado

6 respostas
J

Fala pessoal,

Seguinte, tô com um problema que não estou entendo direito como resolver. Em minha aplicação (JSF2 + Richfaces 4) eu tenho uma tela que é utilizada para preenchimento de um cadastro de usuários (controlada por um mbean do tipo SessionScoped). Após os usuários entrarem com todas as informações, e selecionarem um botão confirmar, o objeto usuário é criado, e o sistema disponibiliza uns botões botões que abrem internamente algumas telas para complemento do cadastro. Cada uma dessas outras telas é controlada por um managedbean do tipo ViewScoped.

Acontece que, após o usuário selecionar o botão criar, os mbeans do tipo ViewScoped são instanciados apenas uma vez. Mesmo eu abrindo outra subtela pelos botões de navegação do cadastro, os mbeans não são recriados.

O Bizarro é que se eu sair e entrar na tela de novo, dai tudo funciona normalmente. Cada tela que eu abro pelos botões dentro da tela de cadastro, o servidor instancia um novo MBean.

Alguém sabe me dizer porque esse comportamento diferente nas duas situações? acho que eu estou perdendo alguma coisa do ciclo de vida dos componentes. Será que o Mbean ficou em algum estado que impossibilita ele de ser destruido, e o servidor criar uma nova instância?

6 Respostas

Alys

E aí cara,

O ViewScoped dura enquanto você estiver na mesma página. Então, quando você sai da página e entra de novo, na verdade o comportamento esperado é que um novo MBean seja criado mesmo. Bem, quando você disse “subtela” eu presumi que você ainda está dentro da mesma página/view, é isso mesmo?

Dá uma lida nesse link, é um dos autores mais feras em JSF que já li, ele explica e ilustra as boas e as ruins desse escopo: The benefits and pitfalls of @ViewScoped

Rendrys

Não é bizarro, é o comportamento normal do ViewScoped. Ele dura enquanto estiver na mesma página.
Como o colega falou, provavelmente as suas subtelas estão dentro de uma mesma página, aí fica somente um bean mesmo…

Hebert_Coelho

Não é bizarro, é o comportamento normal do ViewScoped. Ele dura enquanto estiver na mesma página.
Como o colega falou, provavelmente as suas subtelas estão dentro de uma mesma página, aí fica somente um bean mesmo…Exato!

A única navegação possível de se fazer e continuar com todos os objetos de um MB ViewScoped ativos é com uma action que retorne null. Caso a action retorne algo return mesmaPagina.xhtml; uma nova navegação será executada.

J

Alys:
E aí cara,
Dá uma lida nesse link, é um dos autores mais feras em JSF que já li, ele explica e ilustra as boas e as ruins desse escopo: The benefits and pitfalls of @ViewScoped

Opa! Vou dar uma olhada agora! valeu!!

Não é bizarro, é o comportamento normal do ViewScoped. Ele dura enquanto estiver na mesma página.
Como o colega falou, provavelmente as suas subtelas estão dentro de uma mesma página, aí fica somente um bean mesmo…

Vamos lá, as subtelas são diversos xhtmls controlados por diversos Mbeans, que são abertas dentro de um panel central de uma pagina utilizando o esquema de templates. Todas essas subtelas são ViewScoped, e a tela principal é SessionScoped.

Agora o problema é o seguinte, da primeira vez que eu entro na tela de cadastro, crio um usuário e navego entre essas subtelas, os mbeans ViewScoped são criados apenas uma vez. Assim:

  • Se eu clicar no botão X ele cria o Mbean X
  • Se eu clicar no botão Y ele criar o Mbean Y
  • Se eu clicar no botão X novamente ele NÃO cria o Mbean X.

Agora, se eu sair da tela e entrar novamente:

  • Se eu clicar no botão X ele cria o Mbean X
  • Se eu clicar no botão Y ele criar o Mbean Y
  • Se eu clicar no botão X novamente ele CRIA NOVAMENTE o Mbean X.

Ou seja, a partir do momento que o Usuário esta cadastrado, toda vez que eu abro uma subtela o MBean é recriado. Por isso minha dúvida, pode existir algum estado intermediário que pode ocasionar um erro no ciclo de vida e impossibilitar a destruição e recriação de um novo MBean?

Hebert_Coelho

Você poderia utilizar CDI com ConversationScoped. É um controle manual de estado, quase como uma transação de DB com begin() close().

Ou então você pode transportar os objetos necessários pelo FlashScope, esse post mostra como utilizar esse scope: JSF Exibindo Objeto e Mensagens após Redirect.

J

Pessoal, problema resolvido. Não era nada do que eu estava pensando haha

Vamos lá, vou tentar explicar da melhor maneira.

Quando era aberta a tela, e o cadastro do usuário não tinha sido criado, os botões ficavam com um codigo de usuário null (passado como param para os mbeans das subtelas). Assim que o usuário era criado, um novo código era gerado e uma das subtelas era apresentada por default e carregada automaticamente com o código novo gerado.

Acontece que ocorreu uma refatoração de algumas paginas do sistema, e colocaram o painel de botões em um outro form.

E adivinha o que acontecia quando era criado um novo usuario? A tela era atualizada, mas apenas a parte delimitada pelo form (render="@form")

Dai a tela ficava num estado inconsistente: o usuário já tinha um código gerado, mas os botoes estavam com um código null (por isso abria as telas, mas tudo se perdia, ficando sem informações alguma). Nesse ponto encontrei outro problema, umas NPEs que estavam sendo “comidas”.

E por isso quando eu entrava na tela direto pela consulta de um usuário existente, tudo funcionava perfeitamente.

Esse problema foi bem… bem sutil, pequeno, culpa de falta de atenção. Perdi acho que umas 6 horas com isso.

Mas valeu pessoal pela ajuda!

PS: Perdi esse tempo todo, porque estava convicto que era um problema de escopo do managed bean. Pelo menos aprendi a não tentar “adivinhar” o problema antes de realmente analisá-lo.

Criado 20 de junho de 2012
Ultima resposta 21 de jun. de 2012
Respostas 6
Participantes 4