12 Replies Latest reply on Aug 3, 2007 11:27 AM by Sanne Grinovero

    @DataModel on Stateful beans (broken?)

    Sanne Grinovero Master

      I'll post a simple case confirming the problem but I think the stacktrace below, from our complete application, could be more helpfull.

      Having a bean method returning a List annotated as @DataModel in a stateless bean is working as before (used before Seam 1.2.1)

      @Name("brokenList")
      //@Stateful
      public class BrokenList implements BrokenListIfa {

      public void someOtherMethod(){
      }

      @DataModel
      public List getTestData() {
      List l = new ArrayList();
      l.add("ONE");
      l.add("TWO");
      return "testitem";
      }

      // @Remove @Destroy
      public void destroy() {
      }

      }

      The page used to test is something like this:
      <h:dataTable value="#{brokenList.testData}" var="d">
      <h:column>
      <h:outputText value="#{d}" />
      </h:column>
      </h:dataTable>

      When changing the bean to a Stateful bean (as above when enabling commented lines) Seam throws an exception:

      javax.faces.FacesException: javax.el.PropertyNotFoundException: /index.xhtml @52,57 value="#{brokenList.testData}": Property 'testData' not found on type org.javassist.tmp.java.lang.Object_$$_javassist_0
      at javax.faces.component.UIData.getValue(UIData.java:585)
      at javax.faces.component.UIData.getDataModel(UIData.java:1063)
      at javax.faces.component.UIData.setRowIndex(UIData.java:417)
      at com.sun.faces.renderkit.html_basic.TableRenderer.encodeBegin(TableRenderer.java:85)
      at javax.faces.component.UIComponentBase.encodeBegin(UIComponentBase.java:788)
      at javax.faces.component.UIData.encodeBegin(UIData.java:879)
      at javax.faces.component.UIComponent.encodeAll(UIComponent.java:884)
      at javax.faces.component.UIComponent.encodeAll(UIComponent.java:892)
      at com.sun.facelets.FaceletViewHandler.renderView(FaceletViewHandler.java:577)
      at org.ajax4jsf.framework.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:108)
      at org.ajax4jsf.framework.ajax.AjaxViewHandler.renderView(AjaxViewHandler.java:233)
      at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:106)
      at com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:251)
      at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:144)
      at javax.faces.webapp.FacesServlet.service(FacesServlet.java:245)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:83)
      at org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:87)
      at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
      at org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:63)
      at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
      at org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:46)
      at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
      at org.ajax4jsf.framework.ajax.xmlfilter.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:127)
      at org.ajax4jsf.framework.ajax.xmlfilter.BaseFilter.doFilter(BaseFilter.java:277)
      at org.jboss.seam.web.Ajax4jsfFilter.doFilter(Ajax4jsfFilter.java:40)
      at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
      at org.jboss.seam.debug.hot.HotDeployFilter.doFilter(HotDeployFilter.java:63)
      at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
      at org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:140)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
      at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
      at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:179)
      at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84)
      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
      at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)
      at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.ja


      Actually when looking at our application's stacktrace whe get some more information (don't really now why they are different):

      Caused by: javax.el.ELException: /private/users/readerSearchResult.xhtml @53,44 value="#{readerSearch.codeSearchParm}": Error reading 'codeSearchParm' on type org.javassist.tmp.java.lang.Object_$$_javassist_90
      at com.sun.facelets.el.TagValueExpression.getValue(TagValueExpression.java:76)
      at javax.faces.component.UIOutput.getValue(UIOutput.java:173)
      ... 33 more
      Caused by: javax.ejb.EJBTransactionRolledbackException: could not set property value: readerSearch.readers
      at org.jboss.ejb3.tx.Ejb3TxPolicy.handleInCallerTx(Ejb3TxPolicy.java:87)
      at org.jboss.aspects.tx.TxPolicy.invokeInCallerTx(TxPolicy.java:130)
      at org.jboss.aspects.tx.TxInterceptor$Supports.invoke(TxInterceptor.java:148)
      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
      at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:76)
      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
      at org.jboss.ejb3.stateful.StatefulInstanceInterceptor.invoke(StatefulInstanceInterceptor.java:83)
      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
      at org.jboss.aspects.security.AuthenticationInterceptor.invoke(AuthenticationInterceptor.java:77)
      at org.jboss.ejb3.security.Ejb3AuthenticationInterceptor.invoke(Ejb3AuthenticationInterceptor.java:106)
      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
      at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:46)
      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
      at org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:106)
      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
      at org.jboss.ejb3.stateful.StatefulContainer.localInvoke(StatefulContainer.java:204)
      at org.jboss.ejb3.stateful.StatefulLocalProxy.invoke(StatefulLocalProxy.java:100)
      at $Proxy231.getCodeSearchParm(Unknown Source)
      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:597)
      at org.jboss.seam.util.Reflections.invoke(Reflections.java:21)
      at org.jboss.seam.intercept.RootInvocationContext.proceed(RootInvocationContext.java:31)
      at org.jboss.seam.intercept.ClientSideInterceptor$1.proceed(ClientSideInterceptor.java:72)
      at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:56)
      at org.jboss.seam.ejb.RemoveInterceptor.aroundInvoke(RemoveInterceptor.java:41)
      at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
      at org.jboss.seam.core.SynchronizationInterceptor.aroundInvoke(SynchronizationInterceptor.java:32)
      at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
      at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:106)
      at org.jboss.seam.intercept.ClientSideInterceptor.invoke(ClientSideInterceptor.java:50)
      at org.javassist.tmp.java.lang.Object_$$_javassist_90.getCodeSearchParm(Object_$$_javassist_90.java)
      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:597)
      at javax.el.BeanELResolver.getValue(BeanELResolver.java:62)
      at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:53)
      at com.sun.faces.el.FacesCompositeELResolver.getValue(FacesCompositeELResolver.java:64)
      at org.jboss.el.parser.AstPropertySuffix.getValue(AstPropertySuffix.java:53)
      at org.jboss.el.parser.AstValue.getValue(AstValue.java:67)
      at org.jboss.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:186)
      at com.sun.facelets.el.TagValueExpression.getValue(TagValueExpression.java:71)
      ... 34 more
      Caused by: java.lang.IllegalArgumentException: could not set property value: readerSearch.readers
      at org.jboss.seam.Component.setPropertyValue(Component.java:1660)
      at org.jboss.seam.Component.access$300(Component.java:134)
      at org.jboss.seam.Component$BijectedMethod.set(Component.java:2361)
      at org.jboss.seam.Component.injectDataModelSelection(Component.java:1378)
      at org.jboss.seam.Component.injectDataModelSelections(Component.java:1364)
      at org.jboss.seam.Component.inject(Component.java:1303)
      at org.jboss.seam.core.BijectionInterceptor.aroundInvoke(BijectionInterceptor.java:45)
      at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
      at org.jboss.seam.core.ConversationInterceptor.aroundInvoke(ConversationInterceptor.java:63)
      at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
      at org.jboss.seam.core.MethodContextInterceptor.aroundInvoke(MethodContextInterceptor.java:42)
      at
      2007-07-27 21:44:06,453 ERROR [STDERR] org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
      at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:106)
      at org.jboss.seam.intercept.SessionBeanInterceptor.aroundInvoke(SessionBeanInterceptor.java:53)
      at sun.reflect.GeneratedMethodAccessor147.invoke(Unknown Source)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      at java.lang.reflect.Method.invoke(Method.java:597)
      at org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:118)
      at org.jboss.ejb3.interceptor.EJB3InterceptorsInterceptor.invoke(EJB3InterceptorsInterceptor.java:63)
      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
      at org.jboss.ejb3.entity.ExtendedPersistenceContextPropagationInterceptor.invoke(ExtendedPersistenceContextPropagationInterceptor.java:57)
      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
      at org.jboss.ejb3.entity.TransactionScopedEntityManagerInterceptor.invoke(TransactionScopedEntityManagerInterceptor.java:54)
      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
      at org.jboss.ejb3.AllowedOperationsInterceptor.invoke(AllowedOperationsInterceptor.java:47)
      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
      at org.jboss.aspects.tx.TxPolicy.invokeInCallerTx(TxPolicy.java:126)
      ... 76 more
      Caused by: java.lang.IllegalArgumentException: Could not invoke method by reflection: ReaderSearchActionHibernate.getReaders() with parameters: (java.util.ArrayList) on: it.politecnicoinnovazione.uol2.controller.users.ReaderSearchActionHibernate
      at org.jboss.seam.util.Reflections.invoke(Reflections.java:31)
      at org.jboss.seam.Component.setPropertyValue(Component.java:1656)
      ... 102 more
      Caused by: java.lang.IllegalArgumentException: wrong number of arguments
      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:597)
      at org.jboss.seam.util.Reflections.invoke(Reflections.java:21)
      ... 103 more


      Looking to Seam's source code it looks like it is calling the setter's method to get the value, as our method doesn't have any parameters. "List" should be the return type, not the argument.

      Someone could tell mo more about this? It used to work on Seam 1.2.1
      Should I open a JIRA?

        • 1. Re: @DataModel on Stateful beans (broken?)
          Tiago Newbie

          Not an expert, but I think that the write way to do it is like

          @DataModel
          private List<Hotel> hotels;
          


          (booking example)


          the XHTML page or JSF (JSP style) page would have a reference like


          <a:outputPanel id="searchResults">
           <div class="section">
           <h:outputText value="No Hotels Found" rendered="#{hotels != null and hotels.rowCount==0}"/>
           <h:dataTable id="hotels" value="#{hotels}" var="hot" rendered="#{hotels.rowCount>0}">
           <h:column>
           <f:facet name="header">Name</f:facet>
           #{hot.name}
           </h:column>
          ...
          



          I don't know if your way is possible to do the work, but on the booking example (what I've been writing) the stuff works.


          -------


          • 2. Re: @DataModel on Stateful beans (broken?)
            Sanne Grinovero Master

            thanks a lot, I didn't remember to look there.
            Still when I change the Booking example

            @DataModel
            private List<Hotel> hotels;

            to something like
            @DataModel
            private List<Hotel> getHotels{..}
            I get a very big stacktrace of the same type as above.
            I had preferred to call a method, but knowing this workaround is better than nothing.

            This is actually a migration issue from Seam 1.2.1 to 2, amd I'm still thinking it's a bug as the behaviour is far from expected.

            • 3. Re: @DataModel on Stateful beans (broken?)
              Sanne Grinovero Master

              Hi all, I'm still in need of some good advice; this is currently blocking me.

              Converting the getter method with @DataModel to a simple field is working indeed, but this workaround is difficult to apply. I can't really refactor all my code in a clean way to do this, it breaks "clean code" to very ugly callbacks.. our application is quite complex now and many beans vere designed to use this datamodel on a getter method, as the method is actually a delegate.

              and IF it is a bug I would need to return to old-style code when it is fixed, to clean up the terrible looking code.

              I would really like to know if I have to open a JIRA, as this was working before on seam 1.0.1, 1.1.6, 1.2.0 and 1.2.1 (all which I have used) or if this behaviour will remain so in future editions.

              I would really appreciate some information, thanks a lot.

              • 4. Re: @DataModel on Stateful beans (broken?)
                Gavin King Master

                Are you sure you declared the getter method on the local interface of the SFSB?

                • 5. Re: @DataModel on Stateful beans (broken?)
                  Sanne Grinovero Master

                  Hi Gavin, very nice to see an answer from a guru.. and much congratulations for Seam, I'm really liking it.

                  To answer shortly: YES.

                  • 6. Re: @DataModel on Stateful beans (broken?)
                    Gavin King Master

                    Show us the code of both the bean and the local interface.

                    • 7. Re: @DataModel on Stateful beans (broken?)
                      Sanne Grinovero Master

                      Interface:

                      import javax.ejb.Local;
                      import java.util.List;
                      
                      @Local
                      public interface BrokenListIfa {
                      
                       public List getTestData();
                       public void destroy();
                      
                      }
                      

                      Bean:
                      import org.jboss.seam.annotations.datamodel.DataModel;
                      import org.jboss.seam.annotations.Name;
                      import java.util.ArrayList;
                      import java.util.List;
                      import org.jboss.seam.ScopeType;
                      import javax.ejb.Stateful;
                      import org.jboss.seam.annotations.Scope;
                      import org.jboss.seam.annotations.Destroy;
                      import javax.ejb.Remove;
                      
                      @Name("brokenList")
                      @Stateful
                      public class BrokenList implements BrokenListIfa {
                      
                       @DataModel
                       public List getTestData() {
                       List l = new ArrayList();
                       l.add("ONE");
                       l.add("TWO");
                       return l;
                       }
                      
                       @Remove @Destroy
                       public void destroy() {
                       }
                      
                      }
                      

                      View:
                      <h:dataTable value="#{brokenList.testData}" var="d">
                       <h:column>
                       <h:outputText value="#{d}" />
                       </h:column>
                       </h:dataTable>

                      Partial stacktrace (see first post for more detail):
                      [...]Caused by: java.lang.IllegalArgumentException: Could not invoke method by reflection: BrokenList.getTestData() with parameters: (java.util.ArrayList) on: org.jboss.seam.example.pdf.BrokenList
                      at org.jboss.seam.util.Reflections.invoke(Reflections.java:31)
                      at org.jboss.seam.Component.setPropertyValue(Component.java:1656)
                      ... 108 more
                      Caused by: java.lang.IllegalArgumentException: wrong number of arguments
                      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:597)
                      at org.jboss.seam.util.Reflections.invoke(Reflections.java:21)
                      ... 109 more


                      I must point out that the super-simple test throws the exception but actually renders the expected list. In our application I get the same exception but it doesn't render the page, I suppose because of configuration but am not shure.

                      • 8. Re: @DataModel on Stateful beans (broken?)
                        Tim Newbie

                        I see similar problem before. You need a @Factory on the call to initialize @DataModel list. There's no other way. I spent couple days trying to figure that out with the help of Pete.
                        Check out the link http://www.jboss.com/index.html?module=bb&op=viewtopic&t=114929
                        but here's short answer

                        @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());
                         }
                        }


                        • 9. Re: @DataModel on Stateful beans (broken?)
                          Pete Muir Master

                          I've tried to reproduce this problem and can't. So we're going to need a testcase I think. A patch on an example would be best.

                          • 10. Re: @DataModel on Stateful beans (broken?)
                            Sanne Grinovero Master

                            I made a three-line patch on the booking example, still a trivial change; here is the patch:

                            --- booking/src/org/jboss/seam/example/booking/HotelSearchingAction.java 2007-06-27 08:37:23.000000000 +0200
                            +++ booking-broken/src/org/jboss/seam/example/booking/HotelSearchingAction.java 2007-08-03 01:26:12.000000000 +0200
                            @@ -30,6 +30,7 @@
                             private int page;
                            
                             @DataModel
                            + public List<Hotel> getHotels(){ return hotels; }
                             private List<Hotel> hotels;
                            
                             public void find()
                            diff -ur booking/src/org/jboss/seam/example/booking/HotelSearching.java booking-broken/src/org/jboss/seam/example/booking/HotelSearching.java
                            --- booking/src/org/jboss/seam/example/booking/HotelSearching.java 2007-06-27 08:37:19.000000000 +0200
                            +++ booking-broken/src/org/jboss/seam/example/booking/HotelSearching.java 2007-08-03 01:28:01.000000000 +0200
                            @@ -1,7 +1,8 @@
                             //$Id: HotelSearching.java,v 1.12 2007/06/27 00:06:49 gavin Exp $
                             package org.jboss.seam.example.booking;
                            
                            -import javax.ejb.Local;
                            +import javax.ejb.Local;
                            +import java.util.List;
                            
                             @Local
                             public interface HotelSearching
                            @@ -19,5 +20,7 @@
                             public boolean isNextPageAvailable();
                            
                             public void destroy();
                            +
                            + public List<Hotel> getHotels();
                            
                             }

                            (I just moved the annotation from the field to a new getter with the same name, and declared the getter in the interface)

                            • 11. Re: @DataModel on Stateful beans (broken?)
                              Pete Muir Master

                              Yes, I can reproduce. Please file a bug in JIRA.

                              • 12. Re: @DataModel on Stateful beans (broken?)
                                Sanne Grinovero Master

                                http://jira.jboss.com/jira/browse/JBSEAM-1757

                                tim_ph wrote:

                                I see similar problem before. You need a @Factory on the call to initialize @DataModel list. There's no other way. I spent couple days trying to figure that out with the help of Pete.

                                Thanks tim_ph, I like the workaround you proposed more than mine. Still I'm hoping not having to refactor, as whe used this pattern really often.