JSF CDI Conversation scope -


i have problem cdi scope.

i have bean conversation scoped, clientcontroller, have client , phone object push in service order. when register new client, can push 1 or more phones client. this, have used conversation scope. each request push new phone client executing @postcontruct method, doing bean lose state, giving begin on conversation when push first phone.

at first, guess problem bean configuration, when removed template declared on client page, application works correct. template use bean session scope, control page language user choice.

next has code, , can follow code on github repository link https://github.com/mcqueide/service-order.

clientcontroller.java

package br.com.codeshare.controller;  import java.io.serializable; import java.util.arraylist; import java.util.list; import java.util.map;  import javax.annotation.postconstruct; import javax.enterprise.context.conversation; import javax.enterprise.context.conversationscoped; import javax.enterprise.inject.produces; import javax.faces.application.facesmessage; import javax.faces.context.facescontext; import javax.inject.inject; import javax.inject.named;  import br.com.codeshare.enums.errorcode; import br.com.codeshare.exception.businessexception; import br.com.codeshare.model.client; import br.com.codeshare.model.phone; import br.com.codeshare.qualifiers.sessionmap; import br.com.codeshare.service.clientservice; import br.com.codeshare.service.phoneservice; import br.com.codeshare.util.webresources;  @named @conversationscoped public class clientcontroller implements serializable {      private static final long serialversionuid = 1l;      @inject     private facescontext facescontext;     @inject @sessionmap     private map<string, object> sessionmap;     @inject     private clientservice clientservice;      private client newclient;      @inject     private phonecontroller phonecontroller;     @inject     private phoneservice phoneservice;      @inject     private conversation conversation;      private string filtername;      private list<client> listclients;      private client clientselected;     private list<phone> phonetoberemove;      @produces     @named     public client getnewclient() {         return newclient;     }      @postconstruct     public void initnewclient() {         newclient = new client();         newclient.settelefones(new arraylist<phone>());         listclients = clientservice.findall();     }      public string save() throws exception {         try {             validatephoneleastonephoneobligatory(newclient);              clientservice.save(newclient);             facescontext.addmessage(null, new facesmessage(facesmessage.severity_info, webresources.getmessage("register"),webresources.getmessage("sucess_register")));             initnewclient();         }catch (businessexception e) {             facesmessage m = new facesmessage(facesmessage.severity_error,webresources.getmessage(e.geterrorcode()),"");             facescontext.addmessage(null, m);         }catch (exception e) {             string errormessage = getrooterrormessage(e);             facesmessage m = new facesmessage(facesmessage.severity_error,errormessage,webresources.getmessage("unsuccessful"));             facescontext.addmessage(null, m);         }         if(!conversation.istransient()){             conversation.end();         }         return null;     }      public string update(client client) throws exception{         try {             validatephoneleastonephoneobligatory(client);              clientservice.update(client,phonetoberemove);             facescontext.addmessage(null, new facesmessage(facesmessage.severity_info,  webresources.getmessage("register"),webresources.getmessage("sucess_register")));             initnewclient();         }catch (businessexception e) {             facesmessage m = new facesmessage(facesmessage.severity_error,webresources.getmessage(e.geterrorcode()),"");             facescontext.addmessage(null, m);             return null;         } catch (exception e) {             string errormessage = getrooterrormessage(e);             facesmessage m = new facesmessage(facesmessage.severity_error, errormessage, webresources.getmessage("unsuccessful"));             facescontext.addmessage(null, m);             return null;         }         if(!conversation.istransient()){             conversation.end();         }         return "clients";     }      private void validatephoneleastonephoneobligatory(client client) throws businessexception {         if(client.gethomephone().isempty() && client.getbisenessphone().isempty()){             throw new businessexception(errorcode.least_one_phone_obligatory.geterrorcode());         }     }      private string getrooterrormessage(exception e) {         string errormessage = "registration failed. see server log more information";         if (e == null) {             return errormessage;         }          throwable t = e;         while (t != null) {             errormessage = t.getlocalizedmessage();             t = t.getcause();         }         return errormessage;     }      public void addclientphone() {         if(conversation.istransient()){             conversation.begin();         }          phonecontroller.getnewphone().setclient(newclient);         if (newclient.getphones() == null) {             newclient.settelefones(new arraylist<phone>());         }         newclient.getphones().add(phonecontroller.getnewphone());         phonecontroller.initnewphone();     }      public void removeclientphone(phone phone){         if(conversation.istransient()){             conversation.begin();         }          clientselected.getphones().remove(phone);         if(phonetoberemove == null){             phonetoberemove = new arraylist<phone>();         }         phonetoberemove.add(phone);     }      public void addclientphoneonupdate() {         if(conversation.istransient()){             conversation.begin();         }          phonecontroller.getnewphone().setclient(clientselected);         if (clientselected.getphones() == null) {             clientselected.settelefones(new arraylist<phone>());         }         clientselected.getphones().add(phonecontroller.getnewphone());         phonecontroller.initnewphone();     }      public void searchbyname() {         listclients = null;         if(filtername == null){             listclients = clientservice.findall();         }         listclients = clientservice.findbyname(filtername);     }      public string edit(client client) {         if(conversation.istransient()){             conversation.begin();         }         this.clientselected = client;         list<phone> phonelist = phoneservice.findphonebyclientid(clientselected.getid());         clientselected.settelefones(phonelist);         sessionmap.put("client", client);         return "update_client";     }      public client getclientselected() {         return (client) sessionmap.get("client");     }      public string getfiltername() {         return filtername;     }      public void setfiltername(string filtername) {         this.filtername = filtername;     }      public list<client> getlistclients() {         return listclients;     }  } 

language.java

package br.com.codeshare.util;  import java.io.serializable; import java.util.locale;  import javax.annotation.postconstruct; import javax.enterprise.context.sessionscoped; import javax.faces.context.facescontext; import javax.inject.inject; import javax.inject.named;  @named @sessionscoped public class language implements serializable {      private static final long serialversionuid = 1l;      @inject     private facescontext facescontext;      @postconstruct     public void init(){         localecode = "pt";         countrylocalecodechanged();     }      private string localecode;      public string getlocalecode() {         return localecode;     }      public void setlocalecode(string localecode) {         this.localecode = localecode;     }      // value change event listener     public void countrylocalecodechanged() {         facescontext.getviewroot().setlocale(new locale(localecode));     } } 

client.xhtml

<!doctype html public "-//w3c//dtd xhtml 1.0 transitional//en" "http://www.w3.org/tr/xhtml1/dtd/xhtml1-transitional.dtd">  <ui:composition xmlns="http://www.w3.org/1999/xhtml"     xmlns:h="http://java.sun.com/jsf/html"     xmlns:f="http://java.sun.com/jsf/core"     xmlns:p="http://primefaces.org/ui"     xmlns:ui="http://java.sun.com/jsf/facelets" template="/template.xhtml">      <ui:define name="titulo">         #{label['client.title']}     </ui:define>      <ui:define name="body">         <h:form id="form">             <p:messages />             <p:fieldset legend="#{label['client.fieldset.client']}" id="client">                 <p:panelgrid columns="1" styleclass="panelgrid-semborda">                     <p:outputlabel for="name" value="#{label['client.name']}" />                     <p:inputtext id="name" value="#{newclient.name}" />                      <p:outputlabel for="adress" value="#{label['client.adress']}" />                     <p:inputtext id="adress" value="#{newclient.adress}" />                      <p:fragment rendered='#{!language.localecode.equals("en")}'>                         <p:panelgrid columns="1" styleclass="panelgrid-semborda">                             <p:outputlabel for="homephone_pt" value="#{label['client.homephone']}" />                             <p:inputmask id="homephone_pt" value="#{newclient.homephone}" mask="(99)99999-9999"/>                              <p:outputlabel for="bisenessphone_pt" value="#{label['client.businessphone']}" />                             <p:inputmask id="bisenessphone_pt" value="#{newclient.bisenessphone}" mask="(99)9999-9999"/>                         </p:panelgrid>                     </p:fragment>                      <p:fragment rendered='#{language.localecode.equals("en")}'>                         <p:panelgrid columns="1" styleclass="panelgrid-semborda">                             <p:outputlabel for="homephone_en" value="#{label['client.homephone']}" />                             <p:inputtext id="homephone_en" value="#{newclient.homephone}"/>                              <p:outputlabel for="bisenessphone_en" value="#{label['client.businessphone']}" />                             <p:inputtext id="bisenessphone_en" value="#{newclient.bisenessphone}"/>                         </p:panelgrid>                     </p:fragment>                 </p:panelgrid>             </p:fieldset>             <p:fieldset legend="#{label['client.fieldset.phone']}" id="phones">                 <p:panelgrid id="phone" columns="1" styleclass="panelgrid-semborda">                     <p:outputlabel for="brand" value="#{label['phone.brand']}" />                     <p:inputtext id="brand" value="#{newphone.brand}" />                      <p:outputlabel for="model" value="#{label['phone.model']}" />                     <p:inputtext id="model" value="#{newphone.model}" />                      <p:outputlabel for="state" value="#{label['phone.state']}"/>                     <p:selectoneradio id="state" value="#{newphone.state}">                         <f:selectitems value="#{phonestates}" var="p" itemvalue="#{p}" itemlabel="#{label[p.label]}" />                     </p:selectoneradio>                      <p:outputlabel for="esn" value="#{label['phone.esn']}" />                     <p:inputtext id="esn" value="#{newphone.esn}" />                 </p:panelgrid>                 <p:commandbutton value="#{label['phone.add']}" action="#{clientcontroller.addclientphone}" update="phonetable phones"/>                  <p:datatable value="#{newclient.phones}" var="phone" emptymessage="#{label['phone.notadd']}"                     id="phonetable">                     <p:column headertext="#{label['phone.brand']}">                         <p:outputlabel value="#{phone.brand}"/>                     </p:column>                      <p:column headertext="#{label['phone.model']}">                         <p:outputlabel value="#{phone.model}"/>                     </p:column>                 </p:datatable>             </p:fieldset>             <p:commandbutton action="#{clientcontroller.save}" value="#{label['client.save']}" update="@form"/>           </h:form>     </ui:define> </ui:composition> 

template.xhtml

<?xml version="1.0" encoding="utf-8" ?> <!doctype html public "-//w3c//dtd xhtml 1.0 transitional//en" "http://www.w3.org/tr/xhtml1/dtd/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"      xmlns:f="http://java.sun.com/jsf/core"      xmlns:h="http://java.sun.com/jsf/html"      xmlns:p="http://primefaces.org/ui"      xmlns:ui="http://java.sun.com/jsf/facelets"> <f:view locale="#{language.localecode}" encoding="utf-8"> <h:head>     <title>         <ui:insert name="title"/>     </title>     <link rel="stylesheet" type="text/css" href="resources/css/reset.css" />     <link rel="stylesheet" type="text/css" href="resources/css/style.css" />     <link rel="stylesheet" type="text/css" href="resources/css/fonts/font-awesome.min.css" /> </h:head> <body>     <div class="main">         <div class="menu">             <ui:include src="/menu.xhtml" />         </div>            <div id="body">             <ui:insert name="body"/>         </div>     </div> </body> </f:view> </html> 

menu.xhtml

<?xml version="1.0" encoding="utf-8" ?> <!doctype html public "-//w3c//dtd xhtml 1.0 transitional//en" "http://www.w3.org/tr/xhtml1/dtd/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"      xmlns:f="http://java.sun.com/jsf/core"      xmlns:h="http://java.sun.com/jsf/html"      xmlns:p="http://primefaces.org/ui"      xmlns:ui="http://java.sun.com/jsf/facelets">      <ui:composition>         <p:menubar>             <p:submenu label="#{label['menu.serviceorder']}">                 <p:menuitem value="#{label['menu.serviceorder']}" url="/service-order.jsf"/>                 <p:menuitem value="#{label['menu.serviceorder.new']}" url="/new-service-order.jsf"/>             </p:submenu>             <p:submenu label="#{label['menu.client']}">                 <p:menuitem value="#{label['menu.client.new']}" url="/client.jsf"></p:menuitem>                 <p:menuitem value="#{label['menu.clients']}" url="/clients.jsf"></p:menuitem>             </p:submenu>         </p:menubar>         <h:form class="menu_languages">             <p:selectonemenu value="#{language.localecode}">                 <f:selectitem itemlabel="português" itemvalue="pt" />                 <f:selectitem itemlabel="english" itemvalue="en" />                 <p:ajax listener="#{language.countrylocalecodechanged}" update="@all" />                                     </p:selectonemenu>         </h:form>     </ui:composition>  </html> 

i pretty convinced running 1 of following problems:

  • conversation ends
    • try play @predestroy methods see when conversation vanish
    • make sure not end() conversations earlier (checking code mean calling save/update)
  • new conversation created every time add phone (this cause)
    • when want request associated running conversation, need make use of conversation id (propagate it)
    • note can obtain id calling conversation.getid()
    • to verify this, check url contains given conversation id
    • also note if every time create new conversation, old long-running ones still hanging in there

propagation of conversation done appending cid (conversation id) request url. here quote cdi spec (which suggest read) explaining when conversation propagated automatically:

if current servlet request jsf request, , conversation in long-running state, propagated according following rules:

  • the long-running conversation context associated request renders jsf view automatically propagated faces request (jsf form submission) originates rendered page.

  • the long-running conversation context associated request results in jsf redirect (a redirect resulting navigation rule or jsf navigationhandler) automatically propagated resulting non-faces request, , other subsequent request same url. accomplished via use of request parameter named cid containing unique identifier of conversation.


Comments

Popular posts from this blog

Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.12:test (default-test) on project.Error occurred in starting fork -

windows - Debug iNetMgr.exe unhandle exception System.Management.Automation.CmdletInvocationException -

configurationsection - activeMq-5.13.3 setup configurations for wildfly 10.0.0 -