1 2 Previous Next 15 Replies Latest reply on Sep 17, 2007 2:22 AM by jdijkmeijer

    two @datamodel in one sessionbean?

    jdijkmeijer Newbie

      Hi I'm a bit confused currently I've been doing seam together with icefaces, and I'm very happy with the combination of the both projects.

      However today I run into an issue: when I added a second datamodel to a sessionbean

      @Scope(ScopeType.SESSION)
      @Stateful
      @Name("subjectMgr")
      


      My ear did not deploy anymore, I'm quite confident its the two datamodels on one sessionbean, but I dont see an related messages in the stacktrace:
      subjectMgr, scope: SESSION, type: STATEFUL_SESSION_BEAN, class: nl.jeroen.testdb.persist.SubjectMgrBean, JNDI: spuytear/SubjectMgrBean/local
      12:56:54,666 INFO [com.icesoft.faces.util.event.servlet.ContextEventRepeater] Servlet Context Name: null, Server Info: JBossWeb/2.0.0.GA
      12:56:54,669 WARN [org.jboss.system.ServiceController] Problem starting service jboss.web.deployment:war=spuytwar.war,id=1903303229
      org.jboss.deployment.DeploymentException: URL file:/Applications/jboss-4.2.0.GA/server/default/tmp/deploy/tmp51065spuytear.ear-contents/spuytwar-exp.war/ deployment failed
       at org.jboss.web.tomcat.service.TomcatDeployer.performDeployInternal(TomcatDeployer.java:379)
       at org.jboss.web.tomcat.service.TomcatDeployer.performDeploy(TomcatDeployer.java:104)
       at org.jboss.web.AbstractWebDeployer.start(AbstractWebDeployer.java:375)
       at org.jboss.web.WebModule.startModule(WebModule.java:83)
       at org.jboss.web.WebModule.startService(WebModule.java:61)
       at org.jboss.system.ServiceMBeanSupport.jbossInternalStart(ServiceMBeanSupport.java:289)
       at org.jboss.system.ServiceMBeanSupport.jbossInternalLifecycle(ServiceMBeanSupport.java:245)
       at sun.reflect.GeneratedMethodAccessor3.invoke(Unknown Source)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      

      Leaving one of the two datamodels out of the sessionbean gives a succesful deploy. Is this something I missed in the docs??
      regards,
      Jeroen.

      Versions:
      12:56:36,259 INFO [Server] Release ID: JBoss [Trinity] 4.2.0.GA (build: SVNTag=JBoss_4_2_0_GA date=200705111440)
      12:56:36,494 INFO [ServerInfo] Java VM: Java HotSpot(TM) Client VM 1.5.0_07-87,"Apple Computer, Inc."
      12:56:36,494 INFO [ServerInfo] OS-System: Mac OS X 10.4.10,i386
      Welcome to Seam 1.2.1

        • 1. Re: two @datamodel in one sessionbean?
          Piotr Piwko Newbie

          Try @DataModel(value="name1"), @DataModel(value="name2"). Now you can use them as name1 and name2 in your web pages.

          • 2. Re: two @datamodel in one sessionbean?
            jdijkmeijer Newbie

            That doesnot work for me, behavior is a bit strange and I hope I didnt mess up. See code below:

            package nl.jeroen.testdb.persist;
            
            import java.io.Serializable;
            import java.util.List;
            
            import javax.ejb.Remove;
            import javax.ejb.Stateful;
            
            import nl.jeroen.testdb.session.IApplicationSession;
            
            import org.jboss.seam.ScopeType;
            import org.jboss.seam.annotations.Destroy;
            import org.jboss.seam.annotations.In;
            import org.jboss.seam.annotations.Logger;
            import org.jboss.seam.annotations.Name;
            import org.jboss.seam.annotations.Scope;
            import org.jboss.seam.annotations.datamodel.DataModel;
            import org.jboss.seam.annotations.datamodel.DataModelSelection;
            import org.jboss.seam.log.Log;
            
            @Scope(ScopeType.SESSION)
            @Stateful
            @Name("zzz")
            public class RoleSubjectMgrBean implements Serializable, RoleSubjectMgr {
             private static final long serialVersionUID = -9145745003284315431L;
            
             @Logger
             Log logger;
            
             @DataModel(value="list1")
             private List<String> list1;
            
             @DataModelSelection(value="focusList1")
             private String focusList1;
             public List<String> getList1() {
             return list1;
             }
            
             public void setList1(List<String> list1) {
             this.list1 = list1;
             }
            
             public String getFocusList1() {
             return focusList1;
             }
            
             public void setFocusList1(String focusList1) {
             this.focusList1 = focusList1;
             }
            
             @DataModel(value="list2")
             private List<String> list2;
            
             @DataModelSelection(value="focusList2")
             private String focusList2;
            
             public List<String> getList2() {
             return list2;
             }
             public void setList2(List<String> l2) {
             this.list2 = l2;
             }
             public String getFocusList2() {
             return focusList2;
             }
            
             public void setFocusList2(String focusList2) {
             this.focusList2 = focusList2;
             }
            
             @Destroy @Remove
             public void destroy() {
             }
            
            }
            

            This fails the only way for me to get this working (deploy) is removing the second dataModel(Selection) tags and removing value=".." for dataModelSelection tags, the value=".." for the datamodel doesnot seem to do any harm nor good.

            the errors are still the same errors on deployment of sessionbean:
            17:25:47,588 INFO [org.jboss.seam.Component] Component: zzz, scope: SESSION, type: STATEFUL_SESSION_BEAN, class: nl.jeroen.testdb.persist.RoleSubjectMgrBean, JNDI: spuytear/RoleSubjectMgrBean/local
            17:25:47,671 INFO [com.icesoft.faces.util.event.servlet.ContextEventRepeater] Servlet Context Name: null, Server Info: JBossWeb/2.0.0.GA
            17:25:47,673 WARN [org.jboss.system.ServiceController] Problem starting service jboss.web.deployment:war=spuytwar.war,id=1280645147
            org.jboss.deployment.DeploymentException: URL file:/Applications/jboss-4.2.0.GA/server/default/tmp/deploy/tmp55177spuytear.ear-contents/spuytwar-exp.war/ deployment failed
             at org.jboss.web.tomcat.service.TomcatDeployer.performDeployInternal(TomcatDeployer.java:379)
             at org.jboss.web.tomcat.service.TomcatDeployer.performDeploy(TomcatDeployer.java:104)
            


            thanks for your time,

            jeroen.

            ps ICEFaces is on version 1.6.0


            • 3. Re: two @datamodel in one sessionbean?
              Jacob Orshalick Apprentice

              The value provided for your @DataModelSelection should specify the @DataModel it is related to. Based on your example above,

              ...
              @DataModel(value="list1")
              private List<String> list1;
              
              @DataModelSelection(value="list1")
              private String focusList1;
              ...
              


              This should be specified for each @DataModel and @DataModelSelection in order to allow Seam to determine which @DataModelSelection is associated with which @DataModel. Now, if you want to outject the @DataModelSelection, you will have to do so explicitly through:

              ...
              @DataModel(value="list1")
              private List<String> list1;
              
              @DataModelSelection(value="list1")
              @Out(required=false, value="focusList1")
              private String focusList1;
              ...
              


              The above will allow you to access #{list1} as your @DataModel and #{focusList1} as your @DataModelSelection.

              The getters and setters you specified are not necessary to access these attributes from EL expressions as Seam outjects them directly into the context although you may keep the getters and setters for unit testing (makes sense). Hope that helps.

              • 4. Re: two @datamodel in one sessionbean?
                Piotr Piwko Newbie

                Instead of

                 @DataModel(value="list1")
                 private List<String> list1;
                
                 @DataModelSelection(value="focusList1")
                 private String focusList1;


                use
                 @DataModel(value="list1")
                 private List<String> list1;
                
                 @DataModelSelection(value="list1")
                 private String focusList1;


                so appropriate @DataModel and @DataModelSelection have same value parameter.

                You can also use @Factory to populate list1 when it's empty.

                • 5. Re: two @datamodel in one sessionbean?
                  Jacob Orshalick Apprentice

                  Seam team,

                  I think it might be helpful to adjust the wording of the documentation and maybe add some additional explanation for the @DataModelSelection annotation in relation to @DataModel. The following documentation for @DataModelSelection:

                  value ? name of the conversation context variable. Not needed if there is exactly one @DataModel in the component.


                  seems to indicate to developers that you are naming the @DataModelSelection context variable by specifying the value. The reason I bring it up is, I have heard this same question from every new member of my team when they try to use 2 DataModels in one component. Thanks.

                  • 6. Re: two @datamodel in one sessionbean?
                    Piotr Piwko Newbie

                    @jacob.orshalick

                    Now, if you want to outject the @DataModelSelection, you will have to do so explicitly through:
                    @Out(required=false, value="focusList1")
                    


                    I have outjected DataModel. On the web page I click on selected item from this DataModel but after that I have no DataModelSelection outjected. To get that I execute any method from java bean object during click. Is it possible to have DataModelSelection outjected without "touching" java bean object?

                    • 7. Re: two @datamodel in one sessionbean?
                      Jacob Orshalick Apprentice

                      Let me make sure I understand your question in the context of the previous code...

                      1. You have specified the following:

                      ...
                      @DataModel(value="list1")
                      private List<String> list1;
                      
                      @DataModelSelection(value="list1")
                      @Out(required=false, value="focusList1")
                      private String focusList1;
                      ...
                      


                      2. The user selects an @DataModel in your view list which executes some action.

                      3. The action does not invoke the @DataModelSelection attribute, just logs a statement, say:

                      ...
                      public void select() {
                       log.info("User selected something!");
                      }
                      ...
                      


                      4. Subsequently, in the RENDER_RESPONSE phase you attempt to access the outjected variable #{focusList1} and the context variable is null.

                      In other words, if the @DataModelSelection attribute is not invoked (touched) during the INVOKE_APPLICATION phase, the @DataModelSelection is not loaded. Therefore, no value is outjected to the context to be made available in the RENDER_RESPONSE.

                      Is this correct?

                      • 8. Re: two @datamodel in one sessionbean?
                        Piotr Piwko Newbie

                        Hmm...

                        So, I have a class myObject

                        ...
                        @DataModel(value="list1")
                        private List<String> list1;
                        
                        @DataModelSelection(value="list1")
                        @Out(required=false, value="focusList1")
                        private String focusList1;
                        ...
                        public void select() {
                         log.info("User selected something!");
                        }
                        ...
                        

                        a page, for example
                        <h:dataTable value="#{list1}" var="item">
                         <h:column>
                         <s:link value="#{item}" view="/page2.xhtml"/>
                         </h:column>
                        </h:dataTable>
                        


                        then I click on selected item link and page2.xhtml is
                        <h:outputText value="#{focusList1}">
                        

                        here I have no focusList1 outjected.

                        When I use and click:
                        <h:dataTable value="#{list1}" var="item">
                         <h:column>
                         <s:link value="#{item}" view="/page2.xhtml" action="#{myObject.select()}" />
                         </h:column>
                        </h:dataTable>
                        


                        I have focusList1 outjected and all is OK.

                        Is it possible to have it outjected without using action="#{myObject.select()}"
                        Is there better way to do it?
                        I need sometimes to action property perform diffrent function for example #{secondObject.function()} and can I place both functions in one action property like action="#{secondObject.function()} , #{myObject.select()}" or similar?


                        • 9. Re: two @datamodel in one sessionbean?
                          Jacob Orshalick Apprentice

                          Okay, I now understand the issue...

                          I will explain this from my understanding and maybe a member of the Seam team can validate (or invalidate) this. The use of <s:link>, @DataModel, and @DataModelSelection can get complicated.

                          <s:link value="#{item}" view="/page2.xhtml"/>
                          


                          executes a GET request which will not process the INVOKE_APPLICATION phase but will propagate the conversation. This is similar to the first invocation of a JSF page, but maintains conversation state across the GET request.

                          By specifying an action, this indicates to Seam that the entire JSF lifecycle should be processed for the GET. Thus, the INVOKE_APPLICATION phase gets executed. This is when the @DataModelSelection is populated, explaining why scenario 2 works:

                          <s:link value="#{item}" view="/page2.xhtml" action="#{myObject.select()}" />
                          


                          I believe you will have to invoke an action to retrieve the @DataModelSelection. To my knowledge, all the examples show it this way...

                          In regards to multiple actions for one action, why don't you inject any other components into the component being called on and execute actions from that component. For example, if I have myObject,

                          ...
                          @In
                          SecondObject secondObject;
                          ...
                          public void select() {
                           // do something
                           secondObject.function();
                          }
                          ...


                          • 10. Re: two @datamodel in one sessionbean?
                            Piotr Piwko Newbie

                            Thanks jacob for your answer. I would like to know what Pete Muir thinks about this solution.

                            ...
                            @In
                            SecondObject secondObject;
                            ...
                            public void select() {
                             // do something
                             secondObject.function();
                            }
                            ...
                            


                            • 11. Re: two @datamodel in one sessionbean?
                              Pete Muir Master

                              Jacob, please raise a JIRA issue re the doc improvement. If you can create a patch or suggested wording all the better :)

                              • 12. Re: two @datamodel in one sessionbean?
                                Pete Muir Master

                                This is also not explained well in the docs ;)

                                It's simply that @DataModelSelection is like @In. Unless you actually call a method on the bean the bijections of that bean don't happen (obviously, otherwise at every request all bijection on all Seam components would occur). So unless you do *something* with that bean the injection from @DataModelSelection and the outjection due to @Out won't occur.

                                Add this to JIRA and I'll improve the wording.

                                • 13. Re: two @datamodel in one sessionbean?
                                  Jacob Orshalick Apprentice

                                  Thanks Pete. I will add a JIRA issue and include some wording about the @DataModelSelection if that will help.

                                  1 2 Previous Next