13 Replies Latest reply on Jul 12, 2007 6:21 AM by idylle

    Seam gen edit pages, update without press save button

    rbcdexia

      I have a problem with seam generator edit pages.
      When a generated pojo has a complex object inside it, seam gen generates in the edit page a rich:tab with the following code.

      <rich:tab label="entidad *" labelClass="required">
       <div class="association" id="entidadParent">
      
       <h:outputText value="No entidad"
      
       rendered="#{operacionHome.instance.entidad == null}"/>
      
       <rich:dataTable var="entidad"
       value="#{operacionHome.instance.entidad}"
       rendered="#{operacionHome.instance.entidad != null}"
       rowClasses="rvgRowOne,rvgRowTwo"
       id="entidadTable"
       bypassUpdates="true">
       <h:column>
       <f:facet name="header">empresa</f:facet>
       #{entidad.empresa.nombre}
       </h:column>
       <h:column>
       <f:facet name="header">nombre</f:facet>
       #{entidad.nombre}
       </h:column>
       <h:column>
       <f:facet name="header">numerocnmv</f:facet>
       #{entidad.numerocnmv}
       </h:column>
       <h:column>
       <f:facet name="header">isin</f:facet>
       #{entidad.isin}
       </h:column>
       </rich:dataTable>
      
       <div class="actionButtons">
       <s:button value="Select entidad" bypassUpdates="true"
       view="/EntidadList.xhtml">
       <f:param name="from" value="OperacionEdit"/>
       </s:button>
       </div>
      
       </div>
       </rich:tab>

      When I press the botton and I bring the object entidad the following update is aoutomatically executed without press the save button:

      10:28:30,488 INFO [STDOUT] Hibernate: update fondval.dbo.operacion set entidadid=?, ctapersonasid=?, activoid=?, volumen=?, divisaid=?, sistema=?, precio=?, fecha=?, mercadoid=?, tipoprecio=?, tipo=?, referencia=? where operacionid=?
      


      Can you help me with this question, please?


        • 1. Re: Seam gen edit pages, update without press save button
          pmuir

          Is that supposed to be an edit page or what? I don't understand how you are selecting anything with that button.

          • 2. Re: Seam gen edit pages, update without press save button
            rbcdexia

            I have an object "Operacion" that has inside an object "Entidad".
            I want to edit my Operation object.I want to change Entidad field in Operacion, so for this reason I have to press the botton. When I press the button I show a list of Entidad objects to select one of them. Then when I return to my page seam executes the update of Operaction always.
            I have done some test using properties like bypassUpdates but seam continues doing the update.


            • 3. Re: Seam gen edit pages, update without press save button
              rbcdexia

               

              "rbcdexia" wrote:
              I have an object "Operacion" that has inside an object "Entidad".
              I want to edit my Operation object.I want to change Entidad field in Operacion, so for this reason I have to press the botton. When I press the button I show a list of Entidad objects to select one of them. Then when I return to my page seam executes the update of Operaction always.
              I have done some test using properties like bypassUpdates but seam continues doing the update.



              This is my complete edit page:
              <!DOCTYPE composition 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:s="http://jboss.com/products/seam/taglib"
               xmlns:ui="http://java.sun.com/jsf/facelets"
               xmlns:f="http://java.sun.com/jsf/core"
               xmlns:h="http://java.sun.com/jsf/html"
               xmlns:a="https://ajax4jsf.dev.java.net/ajax"
               xmlns:rich="http://richfaces.ajax4jsf.org/rich"
               template="layout/template.xhtml">
              
              <ui:define name="body">
              
               <h:messages globalOnly="true" styleClass="message" id="globalMessages"/>
              
               <h:form id="operacion" styleClass="edit">
              
               <rich:panel>
               <f:facet name="header">Edit Operacion</f:facet>
              
              
               <s:decorate id="ctapersonasidDecoration" template="layout/edit.xhtml">
               <ui:define name="label">Id Cuenta en personas</ui:define>
               <h:inputText id="ctapersonasid"
               required="true"
               disabled="#{operacionHome.managed}"
               value="#{operacionHome.instance.ctapersonasid}">
               <a:support bypassUpdates="true" event="onblur" reRender="ctapersonasidDecoration"/>
               </h:inputText>
               </s:decorate>
              
               <s:decorate template="layout/display.xhtml">
               <ui:define name="label">Fecha</ui:define>
               <h:inputText id="fechaDecoration2" value="#{operacionHome.instance.fecha}" required="true">
               <s:convertDateTime pattern="MM/dd/yyyy"/>
               </h:inputText>
               <s:selectDate for="fechaDecoration2" startYear="1910" endYear="2007"><img src="img/calendar.gif"/></s:selectDate>
               </s:decorate>
               <!--<s:decorate id="fechaDecoration" template="layout/edit.xhtml">
               <ui:define name="label">fecha</ui:define>
               <h:inputText id="fecha"
               size="16"
               required="true"
               value="#{operacionHome.instance.fecha}">
               <s:convertDateTime type="both" dateStyle="short"/>
              
               </h:inputText>
               </s:decorate>-->
              
               <s:decorate id="volumenDecoration" template="layout/edit.xhtml">
               <ui:define name="label">Volumen</ui:define>
               <h:inputText id="volumen"
               required="true"
               value="#{operacionHome.instance.volumen}"
               size="27">
               <a:support bypassUpdates="true" event="onblur" reRender="volumenDecoration"/>
               </h:inputText>
               </s:decorate>
              
               <s:decorate id="precioDecoration" template="layout/edit.xhtml">
               <ui:define name="label">Precio</ui:define>
               <h:inputText id="precio"
               required="true"
               value="#{operacionHome.instance.precio}"
               size="27">
               <a:support bypassUpdates="true" event="onblur" reRender="precioDecoration"/>
               </h:inputText>
               </s:decorate>
              
               <s:decorate id="tipoprecioDecoration" template="layout/edit.xhtml">
               <ui:define name="label">Tipo de precio</ui:define>
               <h:inputText id="tipoprecio"
               required="true"
               value="#{operacionHome.instance.tipoprecio}">
               <a:support bypassUpdates="true" event="onblur" reRender="tipoprecioDecoration"/>
               </h:inputText>
               </s:decorate>
              
               <s:decorate id="divisaidDecoration" template="layout/edit.xhtml">
               <ui:define name="label">Id Divisa</ui:define>
               <h:inputText id="divisaid"
               required="true"
               value="#{empty divisaDivisaid ? operacionHome.instance.divisaid : operacionHome.instance.divisaid}">
              
               <a:support bypassUpdates="true" event="onblur" reRender="divisaidDecoration"/>
               </h:inputText>
               </s:decorate>
              
               <s:decorate id="activoidDecoration" template="layout/edit.xhtml">
               <ui:define name="label">Id Activo</ui:define>
               <h:inputText id="activoid"
               required="true"
               value="#{empty activoActivoid ? operacionHome.instance.activoid : operacionHome.instance.activoid}">
              
               <a:support bypassUpdates="true" event="onblur" reRender="activoidDecoration"/>
               </h:inputText>
               </s:decorate>
               <s:decorate id="mercadoidDecoration" template="layout/edit.xhtml">
               <ui:define name="label">Id mercado</ui:define>
               <h:inputText id="mercadoid"
               required="true"
               value="#{empty mercadoMercadoid ? operacionHome.instance.mercadoid : operacionHome.instance.mercadoid}">
              
               <a:support bypassUpdates="true" event="onblur" reRender="activoidDecoration"/>
               </h:inputText>
               </s:decorate>
               <s:decorate id="botonDivisa" template="layout/edit.xhtml">
               <ui:define name="label">Seleccionar Divisa</ui:define>
               <s:button value="Select divisa"
               view="/DivisaAccion.xhtml">
               <f:param name="from" value="OperacionEdit"/>
               </s:button>
               </s:decorate>
              
               <s:decorate id="botonActivo" template="layout/edit.xhtml">
               <ui:define name="label">Seleccionar Activo</ui:define>
               <s:button value="Select activo"
               view="/ActivoAccion.xhtml">
               <f:param name="from" value="OperacionEdit"/>
               </s:button>
               </s:decorate>
              
               <s:decorate id="botonMercado" template="layout/edit.xhtml">
               <ui:define name="label">Seleccionar Mercado</ui:define>
               <s:button value="Select mercado"
               view="/MercadoAccion.xhtml">
               <f:param name="from" value="OperacionEdit"/>
               </s:button>
               </s:decorate>
              
               <s:decorate id="tipoDecoration" template="layout/edit.xhtml">
               <ui:define name="label">Tipo</ui:define>
               <h:inputText id="tipo"
               required="true"
               value="#{operacionHome.instance.tipo}">
               <a:support bypassUpdates="true" event="onblur" reRender="tipoDecoration"/>
               </h:inputText>
               </s:decorate>
              
               <s:decorate id="sistemaDecoration" template="layout/edit.xhtml">
               <ui:define name="label">Sistema</ui:define>
               <h:inputText id="sistema"
               required="true"
               value="#{operacionHome.instance.sistema}">
               <a:support bypassUpdates="true" event="onblur" reRender="sistemaDecoration"/>
               </h:inputText>
               </s:decorate>
              
               <s:decorate id="referenciaDecoration" template="layout/edit.xhtml">
               <ui:define name="label">Referencia</ui:define>
               <h:inputText id="referencia"
               required="true"
               size="13"
               maxlength="13"
               value="#{operacionHome.instance.referencia}">
               <a:support bypassUpdates="true" event="onblur" reRender="referenciaDecoration"/>
               </h:inputText>
               </s:decorate>
              
               <div style="clear:both">
               <span class="required">*</span>
               required fields
               </div>
              
               </rich:panel>
              
               <div class="actionButtons">
              
               <h:commandButton id="save"
               value="Save"
               action="#{operacionHome.persist}"
               disabled="#{!operacionHome.wired}"
               rendered="#{!operacionHome.managed}"/>
              
               <h:commandButton id="update"
               value="Save"
               action="#{operacionHome.update}"
               rendered="#{operacionHome.managed}"/>
              
               <h:commandButton id="delete"
               value="Delete"
               action="#{operacionHome.remove}"
               rendered="#{operacionHome.managed}"/>
              
               <s:button id="done"
               value="Done"
               propagation="end"
               view="/Operacion.xhtml"
               rendered="#{operacionHome.managed}"/>
              
               <s:button id="cancel"
               value="Cancel"
               propagation="end"
               view="/#{empty operacionFrom ? 'OperacionList' : operacionFrom}.xhtml"
               rendered="#{!operacionHome.managed}"/>
              
               </div>
               </h:form>
              
              <rich:tabPanel switchType="ajax">
              
               <rich:tab label="entidad *" labelClass="required">
               <div class="association" id="entidadParent">
              
               <h:outputText value="No entidad"
               rendered="#{operacionHome.instance.entidad == null}"/>
              
               <rich:dataTable var="entidad"
               value="#{operacionHome.instance.entidad}"
               rendered="#{operacionHome.instance.entidad != null}"
               rowClasses="rvgRowOne,rvgRowTwo"
               id="entidadTable"
               bypassUpdates="true">
               <h:column>
               <f:facet name="header">empresa</f:facet>
               #{entidad.empresa.nombre}
               </h:column>
               <h:column>
               <f:facet name="header">nombre</f:facet>
               #{entidad.nombre}
               </h:column>
               <h:column>
               <f:facet name="header">numerocnmv</f:facet>
               #{entidad.numerocnmv}
               </h:column>
               <h:column>
               <f:facet name="header">isin</f:facet>
               #{entidad.isin}
               </h:column>
               </rich:dataTable>
              
               <div class="actionButtons">
               <s:button value="Select entidad" bypassUpdates="true"
               view="/EntidadList.xhtml">
               <f:param name="from" value="OperacionEdit"/>
               </s:button>
               </div>
              
               </div>
               </rich:tab>
              </rich:tabPanel>
              </ui:define>
              
              </ui:composition>


              • 4. Re: Seam gen edit pages, update without press save button
                nebukadnezzar

                I've got the same issue...

                Every time a property of EntityHome.instance is set to a new value it get's directly updated in the PersistenceLayer...

                without the need of calling EntityHome.update()

                is there a way to prevent this?

                • 5. Re: Seam gen edit pages, update without press save button
                  idylle

                  Hi,

                  maybe you should put the following in your pages.xml :

                  <begin-conversation join="true" flush-mode="manual" />


                  I think the "flush-mode=manual" will help you. I found a post about this in this forum once but I haven't kept the url, sorry.

                  • 6. Re: Seam gen edit pages, update without press save button
                    nebukadnezzar


                    yes that fixed it -

                    but i've got a small issue remaining...

                    if the property of the EntityHome.instance was set (no update) and go back to the EntityList.xhtml the edited instance shows the new set value

                    i've got to reload the page and the correct original value is shown...

                    i assume i have todo a refresh on the EntityHome.instance whe i leave with out update right?

                    • 7. Re: Seam gen edit pages, update without press save button
                      idylle

                      I've used a workaround for that problem. Not sure it's the right thing to do and I don't know if it can suit in your case :

                      I use "propagation="none" on my button :

                      <s:button id="done"
                       value="Retour"
                       propagation="none"
                       view="/Collectivites.xhtml"
                       rendered="#{collectivitesHome.managed}" />
                      


                      With this, the page doesn't take the new value.


                      • 8. Re: Seam gen edit pages, update without press save button
                        nebukadnezzar

                        but this way the conversation does not end

                        and remains open .... so you hava a small memory leak

                        • 9. Re: Seam gen edit pages, update without press save button
                          idylle

                          You're right, but I haven't find a way to do it clean...

                          • 10. Re: Seam gen edit pages, update without press save button
                            nebukadnezzar

                            I've found an more clean solution

                            here my button:

                            <s:button id="cancel" value="#{messages['Cancel']}"
                             propagation="end" action="#{userHome.cancel}" />


                            and here the userHome.cancel()
                            @End
                            @Rollback
                            public String cancel() {
                             return "canceled";
                            }


                            the Rollback annotation is the important thing.

                            • 11. Re: Seam gen edit pages, update without press save button
                              michaelcourcy

                              propagation="end" and @End

                              Are you not doing the job twice ?

                              • 12. Re: Seam gen edit pages, update without press save button
                                delphi'sghost

                                I've come across this problem before, and pretty much used the same solution to solve it.

                                When you move from your edit page to the view page after canceling your changes, the conversation object itself is re-used, and uses the same entity manager. The entity manager contains an instance of the object you were just editing, and therefore when it 'loads' it, it just uses the version it already has which is dirty.

                                Add the following to the bottom of your template :

                                <h:outputText value="Entity Manager : #{enityManager}"/><br/>
                                <h:outputText value="Conversation : #{conversation}"/>
                                


                                You can see how the same instance is used from one page to the next.

                                So, I just always use explicit saveChanges() and cancelChanges() methods which either saves the changes, or refreshes the entity. Ending the conversation can be handled from the @End annotation, or within the pages.xml or the pageflow depending on the String returned from the method.

                                I don't use the entity home stuff, but it should work the same.

                                • 13. Re: Seam gen edit pages, update without press save button
                                  idylle

                                  Hi,
                                  the Rollback didn't work in my case.

                                  I've kept the flush-mode="manual" but instead of the trick "propagation=none", I've enforced the refresh of my entity before displaying the page (with this in my EntityBean: getEntityManager().refresh(getInstance());)

                                  It works and seems cleaner.