8 Replies Latest reply on Aug 2, 2007 11:33 AM by tim_ph

    show me the right way to access row of datatable with Seam F

    tim_ph

      I've been trying and trying but cannot do a simple thing like this:

       <h:dataTable var="personnel" value="#{applicationHome.personnels}">
       <h:column>
       <f:facet name="header">action</f:facet>
       <s:link value="Select" action="#{applicationHome.selectPersonnel}"/>
       </h:column>
      </h:dataTable>
      

      where applicationHome is generated by Seam-gen and modified a bit
      @Name("applicationHome")
      public class ApplicationHome extends EntityHome<Application>
      {
      ...
       @DataModel
       private List<Personnel> personnels;
       public List<Personnel> getPersonnels()
       {
       if (personnels == null)
       personnels = getInstance() == null ? null : new ArrayList<Personnel>(getInstance().getPersonnels());
       return personnels;
       }
       @DataModelSelection
       @Out(required = false)
       private Personnel personnel;
       @Logger Log log;
       public void selectPersonnel()
       {
       if (personnel == null) log.info("always null here");
       }
      }
      


      I appreciate any help on using new Seam Framework (we want to use seam-gen for business reason).
      Thanks

      - can't use factory with more likely name conflict.
      - have tried selectPersonnel(Personnel p) with #{applicationHome.selectPersonnel(personnel)}- same null result.

        • 1. Re: show me the right way to access row of datatable with Se
          tim_ph

          Correction: when using selectPersonnel(Personnel p) with #{applicationHome.selectPersonnel(personnel)}, it is NOT NULL. But the value is always the value of the first row of the list, no matter what row you click on.

          • 2. Re: show me the right way to access row of datatable with Se
            pmuir

            Try outjecting your datamodel into a longer scope than Request (e.g. page, conversation).

            • 3. Re: show me the right way to access row of datatable with Se
              tim_ph

              When I did that @DataModel(scope=ScopeType.CONVERSATION)
              it failed to deploy with this error

              2007-08-01 10:25:30,590 INFO [org.jboss.seam.Component] Component: applicationHome, scope: CONVERSATION, type: JAVA_BEAN, class: com.insolve.policy.ApplicationHome
              2007-08-01 10:25:30,606 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[localhost].[/tim]] Exception sending context initialized event to listener instance of class org.jboss.seam.servlet.SeamListener
              java.lang.RuntimeException: Could not create Component: applicationHome
               at org.jboss.seam.init.Initialization.addComponent(Initialization.java:908)
               at org.jboss.seam.init.Initialization.installComponents(Initialization.java:839)
               at org.jboss.seam.init.Initialization.init(Initialization.java:506)
               at org.jboss.seam.servlet.SeamListener.contextInitialized(SeamListener.java:34)
               at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3854)
               at org.apache.catalina.core.StandardContext.start(StandardContext.java:4359)
               at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:761)
               at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:741)
               at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:553)
               at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
               at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
               at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
               at java.lang.reflect.Method.invoke(Method.java:585)
               at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:297)
              


              • 4. Re: show me the right way to access row of datatable with Se

                Change your getPersonnels method into a void factory method. Since you are outjecting your DataModel, you don't need to tie it a getter

                <h:dataTable var="personnel" value="#{personnels}">
                 <h:column>
                 <f:facet name="header">action</f:facet>
                 <s:link value="Select" action="#{applicationHome.selectPersonnel}"/>
                 </h:column>
                </h:dataTable>


                @Name("applicationHome")
                public class ApplicationHome extends EntityHome<Application>
                {
                ...
                 @DataModel
                 private List<Personnel> personnels;
                
                 @Factory("personnels")
                 public void fillPersonnels()
                 {
                 if (personnels == null)
                 personnels = getInstance() == null ? null : new ArrayList<Personnel>(getInstance().getPersonnels());
                 }
                
                 @DataModelSelection
                 @Out(required = false)
                 private Personnel personnel;
                
                 @Logger Log log;
                
                 public void selectPersonnel()
                 {
                 if (personnel == null) log.info("always null here");
                 }
                }
                


                • 5. Re: show me the right way to access row of datatable with Se
                  tim_ph

                  Haven't gone far on this. I made it @Factory as you suggest, Smith. Also add @Out for datamodel, otherwise it won't see personnels value on the page.

                  @DataModel
                  @Out(required=false)
                   private List<Personnel> personnels;
                  


                  then stumble on this error:
                  12:51:49,243 ERROR [STDERR] Aug 1, 2007 12:51:49 PM com.sun.facelets.FaceletView
                  Handler handleRenderException
                  SEVERE: Error Rendering View[/policy/ApplicationEdit.xhtml]
                  java.lang.ClassCastException: java.util.ArrayList
                   at org.jboss.seam.databinding.DataModelBinder.isDirty(DataModelBinder.ja
                  va:14)
                   at org.jboss.seam.Component.outjectDataModel(Component.java:1417)
                   at org.jboss.seam.Component.outjectDataModels(Component.java:1402)
                   at org.jboss.seam.Component.outject(Component.java:1357)
                   at org.jboss.seam.core.BijectionInterceptor.aroundInvoke(BijectionInterc
                  eptor.java:47)
                   at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocation
                  Context.java:68)
                   at org.jboss.seam.persistence.ManagedEntityIdentityInterceptor.aroundInv
                  


                  BTW, I work on latest Seam 2.0.0.Beta1 with JBoss 4.2.0GA. I know it's beta, but I want to use the framework.
                  Thanks for the help.

                  • 6. Re: show me the right way to access row of datatable with Se
                    pmuir

                    You don't want to put @Out @DataModel on the same variable.

                    • 7. Re: show me the right way to access row of datatable with Se
                      pmuir

                      Post the whole exception that occurs on startup, there should be some causedby in there.

                      • 8. Re: show me the right way to access row of datatable with Se
                        tim_ph

                        Holly cow! Today, it just works. No problem at all. You are my lucky star, Pete.
                        I removed all the clutters, and leave minimal code in there. Even though I don't like the part where I have to use single string name for Factory, I have to use it for now rather spend more time on this.
                        Here's complete code

                        <h:outputLabel value="No Personnel assigned yet" rendered="#{empty personnels}"/>
                         <rich:dataTable var="personnel"
                         value="#{personnels}"
                         rendered="#{not empty personnels}"
                         rowClasses="rvgRowOne,rvgRowTwo"
                         id="personnelTable">
                         <h:column>
                         <f:facet name="header">action</f:facet>
                         <h:commandLink value="Select" action="#{applicationHome.selectPersonnel}"/>
                         </h:column>
                        </rich:dataTable>
                        


                        and ApplicationHome.java
                        @Name("applicationHome")
                        public class ApplicationHome extends EntityHome<Application>
                        {
                        ...
                         @DataModel
                         private List<Personnel> personnels;
                        
                         @Factory("personnels")
                         public void fillPersonnels()
                         {
                         if (personnels == null)
                         personnels = getInstance() == null ? null : new ArrayList<Personnel>(getInstance().getPersonnels());
                         }
                        
                         @DataModelSelection
                         private Personnel personnel;
                        
                         @Logger Log log;
                        
                         public void selectPersonnel()
                         {
                         if (personnel == null) log.info("personnel is null");
                         else log.info("you have selected personnel " + personnel.getName());
                         }
                        }
                        


                        Using s:link and s:button will reload the whole page, so I have to use h:commandLink and h:commandButton. personnel can then be used to display more info on the same page.
                        Thank you guys, smithbstl and Pete.