Conversation Scope - Conversação não permanece

436 views
Skip to first unread message

Fillipe Aguiar Soares

unread,
Jul 25, 2011, 1:51:43 PM7/25/11
to javasf: JavaServer Faces Group
Olá a todos!

Estou com um problema em trabalhar com um Managed Bean configurado em
@ConversationScoped. Eu inicio uma conversação num metodo set de um
atributo do meu bean (atributo tarefa), mas no segundo request que eu
faço (chamada do metodo salvar), o objeto tarefa é um novo objeto e o
status da conversação está transiente, mesmo sem eu tê-la finalizado.
O primeiro request é chamado de um link em uma coluna de um dataTable
de tarefas, correspondente ao nome do colaborador responsavel por
aquela tarefa.
O segundo request é feito através de um a4j:commandButton dentro de um
popup do richfaces.

Alguém saberia me dizer o que pode estar acontecendo com o escopo?

Obrigado!

------------ MANAGED BEAN -----------------

@Named
@ConversationScoped
public class TarefaController implements Serializable {

private Tarefa tarefa;
private List<Colaborador> colaboradores;

@Inject
private Conversation conversation;

//outros atributos

public void setTarefa(Tarefa tarefa) {
conversation.begin();
this.tarefa = tarefa;
}

public String salvar() {
//
//Salva ou faz update de tarefa no banco
//

if (!conversation.isTransient()) {
conversation.end();
}

return "listaTarefas";

} catch (Exception e) {
e.printStackTrace();
return "";
}
//entre outros metodos
}


--------------- Campo que faz o primeiro request setando o atributo do
bean com a tarefa a ser alterada ---------------

<rich:column>
<f:facet name="header">
<h:outputText value="Colaborador"/>
</f:facet>
<h:outputText
value="#{tarefas.colaborador.nome}" rendered="#{not empty
tarefas.colaborador}"/>
<a4j:commandLink id="adicionaColaborador"
rendered="#{empty tarefas.colaborador}" value="Adicionar Colaborador"
oncomplete="#{rich:component('popupColaboradores')}.show()"
render="popup">
<f:setPropertyActionListener
target="#{tarefaController.tarefa}" value="#{tarefas}"/>
</a4j:commandLink>
</rich:column>




-------------- Popup do XHTML ---------------

<rich:popupPanel id="popupColaboradores" resizeable="true"
height="100" width="350" domElementAttachment="form">

<f:facet name="header">
<h:outputText value="Selecione o colaborador"/>
</f:facet>
<f:facet name="controls">
<h:outputLink value="#"

onclick="#{rich:component('popupColaboradores')}.hide(); return
false;">
X
</h:outputLink>
</f:facet>
<h:panelGrid columns="2">
<h:outputText value="Colaboradores:"/>
<rich:select id="cbbPopupColaboradores"
value="#{tarefaController.tarefa.colaborador}"
converter="#{colaboradorConverter}">
<f:selectItems
value="#{tarefaController.colaboradores}" var="colaborador"
itemLabel="#{colaborador.nome}" itemValue="#{colaborador.nome}"/>
</rich:select>
<br/>
<br/>
<center>
<a4j:commandButton value="Adicionar"
render="panel" action="#{tarefaController.salvar}"
execute="cbbPopupColaboradores"
onclick="#{rich:component('popupColaboradores')}.hide();"/
>
</center>
</h:panelGrid>
</rich:popupPanel>

Rafael Pestano

unread,
Jul 25, 2011, 3:19:27 PM7/25/11
to jav...@googlegroups.com
Felipe, você precisa propagar o cid da conversation durante as requisições  "Não-Faces", leia o capitulo

5.3.2. Conversation propagation

da especificação para mais detalhes: http://docs.jboss.org/weld/reference/1.0.0/en-US/html/scopescontexts.html


Att,

--

Rafael Mauricio Pestano

Graduando em Ciência da Computação
UFRGS


De: Fillipe Aguiar Soares <fillipe...@summa.com.br>
Para: javasf: JavaServer Faces Group <jav...@googlegroups.com>
Enviadas: Segunda-feira, 25 de Julho de 2011 14:51
Assunto: [javasf] Conversation Scope - Conversação não permanece
--
Você recebeu esta mensagem por que é membro do  Javasf
http://groups.google.com/group/javasf

Conheça também o Java Brazil: http://groups.google.com/group/thejavabrazil


Fillipe Aguiar Soares

unread,
Jul 25, 2011, 4:58:55 PM7/25/11
to javasf: JavaServer Faces Group
Obrigado pela indicação Rafael!

Eu ja tinha chegado neste ponto, mas estou com a sensação de que nadei
nadei e morri na praia.
O problema é sim com a propagação da conversação, mas eu não sei como
propagar ela com os componentes q eu estou utilizando (no caso o
a4j:commandButton).

Eu li alguns links que diziam para utilizar s:conversationPropagation
dentro do meu command, mas não funcionou (pra falar a verdade nem tem
esse s: na minha aplicação rs)

alguem aí sabe mais ou menos o caminho das pedras q eu tenho q seguir?

Rafael Pestano

unread,
Jul 25, 2011, 9:07:04 PM7/25/11
to jav...@googlegroups.com
Opa, já tentou

<a4j:commandLink id="adicionaColaborador"
rendered="#{empty tarefas.colaborador}" value="Adicionar Colaborador"
oncomplete="#{rich:component('popupColaboradores')}.show()"
render="popup">
                            <f:setPropertyActionListener
target="#{tarefaController.tarefa}" value="#{tarefas}"/>
                        <f:param name="cid" value="#{tarefaController.conversation.id}"
                        </a4j:commandLink>

lembrando que dessa maneira a requisição será propagada somente durante essa requisição sendo necessario continuar propagando durante as próximas requisições para o bean não "morrer", além disso, caso o usuário dê um refresh na tela a conversação não será propapagada, para resolver esse "problema" você pode passar o cid via url mas pra isso você precisa iniciar a conversação quando entrar na página

algo como: <hcommandButton action="outcome.faces?cid=#{tarefaController.conversation.id}/>"


aqui tem um exemplo de crud que fiz usando conversation do cdi:

1 - essa  é pagina de listagem: http://code.google.com/p/jsf-conventions-framework/source/browse/ConventionsShowcase/src/main/webapp/pages/person/personConversation.xhtml

2 - aqui voce encontra as demais paginas: http://code.google.com/p/jsf-conventions-framework/source/browse/#hg%2FConventionsShowcase%2Fsrc%2Fmain%2Fwebapp%2Fpages%2Fperson

3 - aqui é o metodo chamado quando o usuário clica no botão editar da tabela:
@Override    
protected String afterPrepareUpdate() {  
      beginConversation();        
return "addUserConversation.faces?cid=" + conversation.getId() + "&amp;faces-redirect=true";    
}

4 - você pode fazer clone do projeto via mercurial para ver funcionando passo a passo:
https://rmpe...@code.google.com/p/jsf-conventions-framework/


Espero ter ajudado.
 
Att,

--

Rafael Mauricio Pestano

Graduando em Ciência da Computação
UFRGS


De: Fillipe Aguiar Soares <fillipe...@summa.com.br>
Para: javasf: JavaServer Faces Group <jav...@googlegroups.com>
Enviadas: Segunda-feira, 25 de Julho de 2011 17:58
Assunto: [javasf] Re: Conversation Scope - Conversação não permanece

Fillipe Aguiar Soares

unread,
Jul 26, 2011, 2:39:36 PM7/26/11
to javasf: JavaServer Faces Group
Olá Rafael!

Obrigado pela resposta, eu estou há um tempo nisso novamente, mas
ainda nada.
Fiz o que vc me indicou, mas a conversação parece que é perdida.
O servidor lança essa exception:

org.jboss.weld.context.NonexistentConversationException: WELD-000321
No conversation found to restore for id
at
org.jboss.weld.jsf.WeldPhaseListener.activateConversations(WeldPhaseListener.java:
108)
at
org.jboss.weld.jsf.WeldPhaseListener.beforePhase(WeldPhaseListener.java:
84)
at com.sun.faces.lifecycle.Phase.handleBeforePhase(Phase.java:228)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:99)
at
com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:
113)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:
118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:409)
at
org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:
1534)
at
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:
281)
at
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:
175)
at
org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:
655)
at
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:
595)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:98)
at
com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:
91)
at
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:
162)
at
org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:
326)
at
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:
227)
at
com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:
170)
at
com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:
822)
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:
719)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:
1013)
at
com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:
225)
at
com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:
137)
at
com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:
104)
at
com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:
90)
at
com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:
79)
at
com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:
54)
at
com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:
59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
at com.sun.grizzly.util.AbstractThreadPool
$Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool
$Worker.run(AbstractThreadPool.java:513)
at java.lang.Thread.run(Thread.java:662)

Estou aki tentando, mas não faço a menor idéia de como recuperar essa
conversação, ainda não achei algo explicativo sobre isso, mas parece
que ta esquentando.

Valew pela ajuda, se vc ou mais alguem souber o que poder ser isso
tudo q está acontecendo com minha aplicação, por favor me ajudem a
entender, o maior objetivo, no fim das contas é esse, entender e
aprender a trabalhar com Conversation Scope no JSF + Richfaces.

Obrigado!

Rafael Pestano

unread,
Jul 26, 2011, 5:54:26 PM7/26/11
to jav...@googlegroups.com
Felipe, esse erro é tipo de quando se tenta propagar uma conversação que não existe, ou seja, antes de propagar você tem que ter "startado" ela.


 
Att,

--

Rafael Mauricio Pestano

Graduando em Ciência da Computação
UFRGS


De: Fillipe Aguiar Soares <fillipeagu...@gmail.com>

Para: javasf: JavaServer Faces Group <jav...@googlegroups.com>
Enviadas: Terça-feira, 26 de Julho de 2011 15:39

Assunto: [javasf] Re: Conversation Scope - Conversação não permanece

Fillipe Aguiar Soares

unread,
Jul 28, 2011, 11:32:08 AM7/28/11
to javasf: JavaServer Faces Group
Mas eu startei ela com um conversation.begin().

Meu link do dataTable chama um metodo set do atributo tarefa, que
inicializa a tarefa com os atributos q ela precisa e a conversação,
daí o meu popup chama o metodo salvar pra passar um novo atributo pro
meu objeto tarefa, mas qndo o metodo salvar é chamado, a conversation
não existe mais, ou seja, o objeto tarefa vem com nulo.

Eu fiz testes fora do popup e a conversation ocorre normalmente, esse
problema só acontece qndo eu utilizo o <rich:popupPanel>

Reinaldo Bezerra

unread,
Jul 28, 2011, 5:48:49 PM7/28/11
to jav...@googlegroups.com
Verifique se no seu método faz algo como:

... getConversation() {
        if(conversation.isTransiente()) {
            converstion.begin();
        }
   }


--
Rei

Rafael Ponte

unread,
Aug 2, 2011, 9:50:36 PM8/2/11
to jav...@googlegroups.com
Por "baixo do panos", para que o conversation scope do Seam funcione é necessário que a cada requisição do cid (conversation id) seja transferido entre as requisições, se ele não for então o escopo é perdido ou reiniciado. É como se cada cid guardasse uma parte da session isolada.

Você consegue ver se o parâmetro é transferido com uma ferramenta como Firebug do Firefox ou qualquer outra! 

2011/7/28 Reinaldo Bezerra <reinal...@gmail.com>



--
Rafael Ponte
http://www.rponte.com.br
Reply all
Reply to author
Forward
0 new messages