11 Replies Latest reply on Jan 15, 2007 3:40 PM by fredbene

    Problem with DataModelSelection?

      I've run across a problem which I haven't been able to figure out thus far - I have a form displaying a record for updating, and underneath that form I have a datatable with the children records, which you can click on a button next to and bring them up in a form of their own. It all seems to work ok, but if there are multiple children in the list, no matter which one you click on it always injects the first one into the variable I have annotated with DataModelSelection. I know the backing List is correct, I have looked at it in debug, but I can't figure out why the wrong entity is being injected =/ I'm letting the List be populated by the entityManager, I have my associations set up and I just get the List that is the entityManager fetches.

      The function which takes the selected entity and sets up the next form begins a nested conversation - this shouldn't matter right?

      Has anyone seen anything like this before? Any ideas?

        • 1. Re: Problem with DataModelSelection?

          Sorry, forgot to add:
          using Jboss 4.0.5GA, was using seam 1.1 CR2, just upgraded to seam 1.1GA but still has the same problem.

          Maybe its something I'm doing - any ideas?

          Any help is much appreciated...

          • 2. Re: Problem with DataModelSelection?

            You'll have to show some code.

            • 3. Re: Problem with DataModelSelection?

              Certainly... Here's the two most relevant snippets, let me know if there's something else that would be helpful...

              
              @Name("eTDocumentEditor")
              @Stateful
              @SerializedConcurrentAccess
              @Interceptors(SeamInterceptor.class)
              public class ETDocumentEditorBean implements ETDocumentEditor {
              
               @In(create = true)
               private EntityManager entityManager;
              
               @Valid
               private ETDocument instance = new ETDocument();
              
               private boolean startConv = true;
              
               @DataModel
               private List<ETContact> contactList;
              
               @DataModelSelection
               private ETContact selectedETContact;
              
               @In(create = true)
               private ETContactEditor eTContactEditor;
              
               @In(create = false, required = false)
               private ETContactFinder eTContactFinder;
              
               private boolean isNew = true;
              
               private boolean isChild = true;
              
               private String doneOutcome = "find";
              
               private String doneChildOutcome = "doneChild";
              
               @In(required = false)
               private transient ETDocumentFinder eTDocumentFinder;
              
               @In(create = true)
               private transient ResourceBundle resourceBundle;
              
               @TransactionAttribute(NOT_SUPPORTED)
               public ETDocument getInstance() {
               return instance;
               }
              
               @TransactionAttribute(NOT_SUPPORTED)
               public void setInstance(ETDocument instance) {
               this.instance = instance;
              
               }
              
               @TransactionAttribute(NOT_SUPPORTED)
               public boolean isNew() {
               return isNew;
               }
              
               public void setNew(boolean isNew) {
               this.isNew = isNew;
               }
              
               @TransactionAttribute(NOT_SUPPORTED)
               public boolean isChild() {
               return isChild;
               }
              
               @TransactionAttribute(NOT_SUPPORTED)
               public void setChild(boolean isChild) {
               this.isChild = isChild;
               }
              
               @TransactionAttribute(NOT_SUPPORTED)
               public void setDoneOutcome(String outcome) {
               doneOutcome = outcome;
               }
              
               @TransactionAttribute(NOT_SUPPORTED)
               public void setDoneChildOutcome(String outcome) {
               doneChildOutcome = outcome;
               }
              
               public String create() {
               if (entityManager.find(ETMaster.class, instance.getPartkey()) == null ) {
               FacesContext.getCurrentInstance().addMessage(
               null,
               new FacesMessage("This violates a constraint!"));
               FacesContext.getCurrentInstance().addMessage(
               null,
               new FacesMessage("There is no EiTradeMaster record with a primary key of " +
               instance.getPartkey()));
               return null;
               }
              
               entityManager.persist(instance);
               isNew = false;
               refreshFinder();
               return null;
               }
              
               @End(ifOutcome = {"find", "doneChild"})
               public String update() {
               refreshFinder();
               return isChild ? doneChildOutcome : doneOutcome;
               }
              
               @End(ifOutcome = {"find", "doneChild"})
               public String delete() {
               entityManager.remove(instance);
               entityManager.flush();
               refreshFinder();
               return isChild ? doneChildOutcome : doneOutcome;
               }
              
               @Begin(nested=true)
               public String updateAndCreateChild() {
               eTContactEditor.setInstance(new ETContact());
               eTContactEditor.setDocConInstance(new ETDocContact(
               new ETDocContactId(instance.getDocId(), null)));
               eTContactEditor.setNew(true);
               eTContactEditor.setChild(true);
               refreshFinder();
               return "child";
               }
              
               @End(ifOutcome = {"find", "doneChild"})
               public String done() {
              
               if (!isNew)
               entityManager.refresh(instance);
               return isChild ? doneChildOutcome : doneOutcome;
               }
              
               @Begin(nested=true)
               public String selectContact() {
               eTContactEditor.setInstance(selectedETContact);
               eTContactEditor.setDocConInstance(entityManager.find(ETDocContact.class,
               new ETDocContactId(instance.getDocId(), selectedETContact.getContactkey())));
               eTContactEditor.setNew(false);
               eTContactEditor.setChild(true);
              
               return "editEiTradeContact";
               }
              
               @TransactionAttribute(NOT_SUPPORTED)
               public String reorderChildren() {
               eTContactFinder.setDocumentKey(instance.getDocId());
               eTDocumentFinder.reorder();
               return null;
               }
              
               @TransactionAttribute(NOT_SUPPORTED)
               public String findChildren() {
               contactList = instance.getContacts();
               return null;
               }
              
               public List<ETContact> getContactList() {
               return contactList;
               }
              
               private void refreshFinder() {
               if (eTDocumentFinder != null) {
               eTDocumentFinder.refresh();
               }
               }
              
               @Destroy
               @Remove
               public void destroy() {
               }
              
               public ETContactFinder getETContactFinder() {
               return eTContactFinder;
               }
              
               public void setETContactFinder(ETContactFinder contactFinder) {
               eTContactFinder = contactFinder;
               }
              
               public void setContactList(List<ETContact> contactList) {
               this.contactList = contactList;
               }
              
              }
              ...
              
              
              
              editEiTradeDocument:
              
              <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
              <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
              <%@ taglib uri="http://javascript4jsf.dev.java.net/" prefix="j4j" %>
              <%@ taglib uri="http://jboss.com/products/seam/taglib" prefix="s" %>
              <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
              <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
               <f:view>
               <f:loadBundle basename="messages" var="msg"/>
               <head>
               <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
               <meta http-equiv="Content-Script-Type" content="text/javascript" />
               <title>
               <h:outputText value="#{msg.Create} #{msg.EiTradeDocument}" rendered="#{eTDocumentEditor.new}"/>
               <h:outputText value="#{msg.Update}/#{msg.Delete} #{msg.EiTradeDocument}" rendered="#{!eTDocumentEditor.new}"/>
               </title>
               <style type="text/css" media="all">
               @import "style/default/screen.css";
               </style>
               </head>
               <body>
               <h:form>
              
               <h1>
               <h:outputText value="#{msg.Create} #{msg.EiTradeDocument}" rendered="#{eTDocumentEditor.new}"/>
               <h:outputText value="#{msg.Update}/#{msg.Delete} #{msg.EiTradeDocument}" rendered="#{!eTDocumentEditor.new}"/>
               </h1>
              
               <div class="rvgSwitch">
               <h:selectOneMenu value="#{switcher.conversationIdOrOutcome}">
               <f:selectItem itemLabel="Create EiTradeDocument" itemValue="editEiTradeDocument"/>
               <f:selectItem itemLabel="Create EiTradeContact" itemValue="editEiTradeContact"/>
               <f:selectItem itemLabel="Create EiTradeMaster" itemValue="editEiTradeMaster"/>
               <f:selectItem itemLabel="Create EiTradeUomXref" itemValue="editEiTradeUomXref"/>
               <f:selectItem itemLabel="Find EiTradeDocument" itemValue="findEiTradeDocument"/>
               <f:selectItem itemLabel="Find EiTradeContact" itemValue="findEiTradeContact"/>
               <f:selectItem itemLabel="Find EiTradeMaster" itemValue="findEiTradeMaster"/>
               <f:selectItem itemLabel="Find EiTradeUomXref" itemValue="findEiTradeUomXref"/>
               <f:selectItems value="#{switcher.selectItems}"/>
               </h:selectOneMenu>
               <h:commandButton action="#{switcher.select}" value="Switch"/>
               </div>
              
               <div class="rvgChildren">
               <fieldset class="rvgFieldSet">
               <legend><h:outputText value="#{msg.EiTradeDocument} #{msg.Attributes}"/></legend>
              
               <span class="rvgInputs">
               <span class="rvgMessage"><h:messages globalOnly="true"/></span>
               <s:validateAll>
               <h:panelGrid columns="4" headerClass="rvgInputs">
               <h:outputLabel value="#{msg.EiTradeDocument_documentkey}" for="docId">
               <h:inputText value="#{eTDocumentEditor.instance.docId}" id="docId" disabled="true"/>
               <span class="rvgMessage"><h:message for="docId"/></span>
               </h:outputLabel>
               <h:outputLabel value="#{msg.EiTradeDocument_isaidkey}" for="isaidkey">
               <h:inputText value="#{eTDocumentEditor.instance.isaidkey}" id="isaidkey" disabled="#{eTDocumentEditor.child}" required="true"/>
               <span class="rvgMessage"><h:message for="isaidkey"/></span>
               </h:outputLabel>
               <h:outputLabel value="#{msg.EiTradeDocument_partkey}" for="partkey">
               <h:inputText value="#{eTDocumentEditor.instance.partkey}" id="partkey" disabled="#{eTDocumentEditor.child}" required="true"/>
               <span class="rvgMessage"><h:message for="partkey"/></span>
               </h:outputLabel>
               <h:outputLabel value="#{msg.EiTradeDocument_tsetid}" for="tsetid">
               <h:inputText value="#{eTDocumentEditor.instance.tsetid}" id="tsetid" required="true"/>
               <span class="rvgMessage"><h:message for="tsetid"/></span>
               </h:outputLabel>
               <h:outputLabel value="#{msg.EiTradeDocument_direction}" for="direction">
               <h:inputText value="#{eTDocumentEditor.instance.direction}" id="direction" required="true"/>
               <span class="rvgMessage"><h:message for="direction"/></span>
               </h:outputLabel>
               <h:outputLabel value="#{msg.EiTradeDocument_partnerGsId}" for="partnerGsId">
               <h:inputText value="#{eTDocumentEditor.instance.partnerGsId}" id="partnerGsId"/>
               <span class="rvgMessage"><h:message for="partnerGsId"/></span>
               </h:outputLabel>
               <h:outputLabel value="#{msg.EiTradeDocument_burrisGsId}" for="burrisGsId">
               <h:inputText value="#{eTDocumentEditor.instance.burrisGsId}" id="burrisGsId"/>
               <span class="rvgMessage"><h:message for="burrisGsId"/></span>
               </h:outputLabel>
               <h:outputLabel value="#{msg.EiTradeDocument_loc}" for="loc">
               <h:inputText value="#{eTDocumentEditor.instance.loc}" id="loc" required="true"/>
               <span class="rvgMessage"><h:message for="loc"/></span>
               </h:outputLabel>
               <h:outputLabel value="#{msg.EiTradeDocument_ediset}" for="ediset">
               <h:inputText value="#{eTDocumentEditor.instance.ediset}" id="ediset" required="true"/>
               <span class="rvgMessage"><h:message for="ediset"/></span>
               </h:outputLabel>
               <h:outputLabel value="#{msg.EiTradeDocument_rptid}" for="rptid">
               <h:inputText value="#{eTDocumentEditor.instance.rptid}" id="rptid"/>
               <span class="rvgMessage"><h:message for="rptid"/></span>
               </h:outputLabel>
               <h:outputLabel value="#{msg.EiTradeDocument_tstprod}" for="tstprod">
               <h:inputText value="#{eTDocumentEditor.instance.tstprod}" id="tstprod" required="true"/>
               <span class="rvgMessage"><h:message for="tstprod"/></span>
               </h:outputLabel>
               <h:outputLabel value="#{msg.EiTradeDocument_billto}" for="billto">
               <h:inputText value="#{eTDocumentEditor.instance.billto}" id="billto"/>
               <span class="rvgMessage"><h:message for="billto"/></span>
               </h:outputLabel>
               <h:outputLabel value="#{msg.EiTradeDocument_chrgcode}" for="chrgcode">
               <h:inputText value="#{eTDocumentEditor.instance.chrgcode}" id="chrgcode"/>
               <span class="rvgMessage"><h:message for="chrgcode"/></span>
               </h:outputLabel>
               </h:panelGrid>
               </s:validateAll>
               </span>
              
               <span class="rvgActions">
               <h:commandButton type="submit" value="#{msg.Create}" action="#{eTDocumentEditor.create}" rendered="#{eTDocumentEditor.new}" accesskey="c"><j4j:defaultAction/> </h:commandButton>
               <h:commandButton type="submit" value="#{msg.Update}" action="#{eTDocumentEditor.update}" rendered="#{!eTDocumentEditor.new}" accesskey="u"><j4j:defaultAction/> </h:commandButton>
               <h:commandButton type="submit" value="#{msg.Delete}" action="#{eTDocumentEditor.delete}" rendered="#{!eTDocumentEditor.new}" accesskey="d"/>
               <h:commandButton type="submit" value="#{msg.Done}" action="#{eTDocumentEditor.done}" immediate="true" accesskey="e"/>
               <h:commandButton type="submit" value="#{msg.SaveAndCreate} #{msg.EiTradeContact}" action="#{eTDocumentEditor.updateAndCreateChild}" accesskey="s" rendered="#{!eTDocumentEditor.new}"/>
              
               </span>
              
               </fieldset>
               </div>
              
               <div class="rvgChildren">
              
               <h2>
               <h:outputText value="Associated Contacts" rendered="true"/>
               </h2>
              
               <div class="rvgChildren">
               <h:outputText value="#{msg.No} #{msg.EiTradeContact} #{msg.MatchedSearchCriteria}" rendered="#{!eTDocumentEditor.hasContacts"/>
              
               <h:dataTable value="#{eTDocumentEditor.contactList}" var="eTContact" rendered="true"
               rowClasses="rvgRowOne,rvgRowTwo" headerClass="rvgOrder">
               <h:column>
               <f:facet name="header">
               <h:commandLink value="#{msg.EiTradeContact_contactkey}">
               <f:param name="orderBy" value="contactkey"/>
               </h:commandLink>
               </f:facet>
               <h:outputText value="#{eTContact.contactkey}"/>
               </h:column>
               <h:column>
               <f:facet name="header">
               <h:commandLink value="#{msg.EiTradeContact_name}">
               <f:param name="orderBy" value="name"/>
               </h:commandLink>
               </f:facet>
               <h:outputText value="#{eTContact.name}"/>
               </h:column>
               <h:column>
               <f:facet name="header">
               <h:commandLink value="#{msg.EiTradeContact_atten}">
               <f:param name="orderBy" value="atten"/>
               </h:commandLink>
               </f:facet>
               <h:outputText value="#{eTContact.atten}"/>
               </h:column>
               <h:column>
               <f:facet name="header">
               <h:commandLink value="#{msg.EiTradeContact_addr1}">
               <f:param name="orderBy" value="addr1"/>
               </h:commandLink>
               </f:facet>
               <h:outputText value="#{eTContact.addr1}"/>
               </h:column>
               <h:column>
               <f:facet name="header">
               <h:commandLink value="#{msg.EiTradeContact_addr2}">
               <f:param name="orderBy" value="addr2"/>
               </h:commandLink>
               </f:facet>
               <h:outputText value="#{eTContact.addr2}"/>
               </h:column>
               <h:column>
               <f:facet name="header">
               <h:commandLink value="#{msg.EiTradeContact_addr3}">
               <f:param name="orderBy" value="addr3"/>
               </h:commandLink>
               </f:facet>
               <h:outputText value="#{eTContact.addr3}"/>
               </h:column>
               <h:column>
               <f:facet name="header">
               <h:commandLink value="#{msg.EiTradeContact_city}" >
               <f:param name="orderBy" value="city"/>
               </h:commandLink>
               </f:facet>
               <h:outputText value="#{eTContact.city}"/>
               </h:column>
               <h:column>
               <f:facet name="header">
               <h:commandLink value="#{msg.EiTradeContact_state}" >
               <f:param name="orderBy" value="state"/>
               </h:commandLink>
               </f:facet>
               <h:outputText value="#{eTContact.state}"/>
               </h:column>
               <h:column>
               <f:facet name="header">
               <h:commandLink value="#{msg.EiTradeContact_zip}" >
               <f:param name="orderBy" value="zip"/>
               </h:commandLink>
               </f:facet>
               <h:outputText value="#{eTContact.zip}"/>
               </h:column>
               <h:column>
               <f:facet name="header">
               <h:commandLink value="#{msg.EiTradeContact_phone}" >
               <f:param name="orderBy" value="phone"/>
               </h:commandLink>
               </f:facet>
               <h:outputText value="#{eTContact.phone}"/>
               </h:column>
               <h:column>
               <f:facet name="header">
               <h:commandLink value="#{msg.EiTradeContact_cell}" >
               <f:param name="orderBy" value="cell"/>
               </h:commandLink>
               </f:facet>
               <h:outputText value="#{eTContact.cell}"/>
               </h:column>
               <h:column>
               <f:facet name="header">
               <h:commandLink value="#{msg.EiTradeContact_email}" >
               <f:param name="orderBy" value="email"/>
               </h:commandLink>
               </f:facet>
               <h:outputText value="#{eTContact.email}"/>
               </h:column>
              
               <h:column>
               <f:facet name="header"><h:outputText value="#{msg.Action}"/></f:facet>
               <h:commandButton action="#{eTDocumentEditor.selectContact}" value="#{eTContactSelector.buttonLabel}"/>
               </h:column>
               </h:dataTable>
               </div>
               </div>
              
              
               </h:form>
              
               </body>
               </f:view>
              </html>
              
              


              • 4. Re: Problem with DataModelSelection?

                Is there any other code that would help? I'm still at a loss....

                Thanks.

                • 5. Re: Problem with DataModelSelection?

                  Ah ha!!

                  I got it working... I'm not really sure why it was always injecting the first element into the DataModelSelection variable, it still feels like something was broken or I was grossly missing something. But I took the DataModel and DataModelSelection variables out of the Editor bean and put them, along with query logic (instead of relying on the natural fetch functionality of the entityManager) in the Finder bean. It now works, but I don't really know why this made any difference...

                  Thanks.

                  • 6. Re: Problem with DataModelSelection?
                    jim.farley

                    Did you change anything else to get this to work? I'm seeing the same behavior (in an app running Seam 1.0.1), and can't isolate the issue. The JSF ListDataModel seems to be using a rowIndex of 0 no matter which item I select. I've restructured the code and configuration to resemble the DVD JBoss example, and now your code, but the broken behavior remains.

                    • 7. Re: Problem with DataModelSelection?
                      jim.farley

                      More on this: it seems that the @DataModel variable is not being set up as a context variable for some reason. When the Seam phase listener looks for it (in selectDataModelRow()) to set its index to match the link index, it's not found in any context, so the wrapped ListDataModel's internal index remains unset (defaults to zero). Hence the first item is picked each time.

                      It still alludes me why my @DataModel is not being put into conversation context while the dvd example does behave as expected. To try to isolate the problem, I've restructured the code along the lines of the dvd example (specifically, the showorders.xhtml page), and lined up my components.xml, web.xml and faces-config.xml to the settings in the dvd example. Any ideas would be very welcome.

                      • 8. Re: Problem with DataModelSelection?

                        Nope that was all I changed- there was one thing that occured to me this morning though, but I haven't played with this so I don't know if this makes a difference or not - my Editor bean is conversation scoped, my Finder bean is session scoped. @DataModel has a scope parameter, but from the javadocs,

                        Outjects a collection to the same scope as the owning component (or to the EVENT scope in the case of a stateless component)...


                        Let me know if you figure out what exactly causes this behavior.

                        Thanks.

                        • 9. Re: Problem with DataModelSelection?
                          jim.farley

                          It was a scope problem - I had to put the initialization of the DataModel into an explicit conversation scope (added an @Begin to the load method). I was using an implicit conversation before, and the conversation was cutting off between the display of the select list and the display of the selected item. This lines up with your session/conversation explanation as well.

                          • 10. Re: Problem with DataModelSelection?
                            mterring

                            I had a similar problem with the same symptoms. Turns out that in the XHTML the dataTable value was "#{component.list}" instead of "#{list}". This works fine for displaying the list, but on the return Seam can't find the DataModelSelection for "component.list" since it expects it to be for "list".

                            • 11. Re: Problem with DataModelSelection?
                              fredbene

                              I change here from @Create to @Factory, and worked to me!