11 Replies Latest reply on Mar 30, 2007 10:17 PM by Brian Smith

    @DataModel problems

    Brian Smith Apprentice

      I keep getting this returned via the debug page under my datamodel component. Why is the row unavailable? The wrapped data is some of the data returned via my query but the data model is not being displayed on the page. No exception is thrown.

      class class org.jboss.seam.jsf.ListDataModel
      dataModelListeners []
      rowAvailable false
      rowCount 1
      rowData java.lang.IllegalArgumentException[row is unavailable]
      rowIndex -1
      wrappedData [com.stlouiscity.csb.ejb.domain.Address[structureAddressPK=com.stlouiscity.csb.ejb.domain.AddressPK[sadrNlc=720, sadrHseNoSfx= , sadrHseNoLegl=6047]]]
      toString() org.jboss.seam.jsf.ListDataModel@1eca460


      Here is my SFSB
      @Stateful
      @Name("addressListing")
      @Scope(ScopeType.SESSION)
      public class AddressListing implements mypackage.AddressListingLocal {
      
       //@EJB private AddressLocatorLocal locator;
       @PersistenceContext(unitName="CSB_Oracle", type=EXTENDED)
       private EntityManager em;
      
       @In(create=true)
       FacesMessages facesMessages;
      
       @In
       private Address address;
      
       private Integer addressLookupPK;
      
       @DataModel
       private List<StructureAddress> addresses;
      
       @Out(required=false)
       private List<String> streetDirections;
      
       public AddressListing() {
       }
      
       public String findAddresses() {
      
       if (address.getStreetName() != null) {
       //Find StructureAddress
       Query q = em.createQuery("Select a From StructureAddress a Where" +
       " (a.structureAddressPK.houseNumber = :houseNumber OR :houseNumber IS NULL) AND" +
       " (a.structureAddressPK.houseSuffix = :suffix OR :suffix IS NULL) AND" +
       " (a.nlc.streetDirection = :streetDirection OR :streetDirection IS NULL) AND" +
       " (lower(a.nlc.streetName) LIKE :street OR :street IS NULL)");
       q.setParameter("houseNumber",address.getHouseNumber());
       q.setParameter("suffix",address.getHouseSuffix());
       q.setParameter("streetDirection",address.getStreetDirection());
       q.setParameter("street",address.getStreetName().toLowerCase() + "%");
       addresses = q.getResultList();
       }
      
       return null;
       }
      
       @Factory("streetDirections")
       public void fillStreetDirections() {
       Query query = em.createQuery("SELECT DISTINCT n.streetDirection FROM Nlc n WHERE n.streetDirection IS NOT NULL");
       streetDirections = query.getResultList();
       }
      
       @Remove @Destroy
       public void destroy() {
      
       }
      }
      


      Here is the page

      <tr:outputText value="No Addresses Found" rendered="#{empty addresses and addresses!=null}"/>
       <tr:table
       id="addresses"
       var="addressRow"
       value="#{addresses}"
       rowBandingInterval="1"
       rendered="#{addresses!=null}"
       rowSelection="single"
       partialTriggers="addressForm:search">
       <tr:column>
       <f:facet name="header">
       <tr:outputText value="#{msgs['AddressList.addressNumber']}"/>
       </f:facet>
       <s:link id="viewRequests" value="Requests" action="#{addressListing.findRequests}"/>
       </tr:column>
       <tr:column>
       <f:facet name="header">
       <tr:outputText value="#{msgs['AddressList.addressNumber']}"/>
       </f:facet>
       <tr:outputText value="#{addressRow.structureAddressPK.houseNumber}"/>
       </tr:column>
       <tr:column>
       <f:facet name="header">
       <tr:outputText value="#{msgs['AddressList.addressSuffix']}"/>
       </f:facet>
       <tr:outputText value="#{addressRow.structureAddressPK.houseSuffix}"/>
       </tr:column>
      
      
       <tr:column>
       <f:facet name="header">
       <tr:outputText value="#{msgs['AddressList.streetDirection']}"/>
       </f:facet>
       <tr:outputText value="#{addressRow.nlc.streetDirection}"/>
       </tr:column>
       <tr:column>
       <f:facet name="header">
       <tr:outputText value="#{msgs['AddressList.street']}"/>
       </f:facet>
       <tr:outputText value="#{addressRow.nlc.streetName}"/>
       </tr:column>
       <tr:column>
       <f:facet name="header">
       <tr:outputText value="#{msgs['AddressList.streetType']}"/>
       </f:facet>
       <tr:outputText value="#{addressRow.nlc.streetType}"/>
       </tr:column>
       </tr:table>


        • 1. Re: @DataModel problems
          Stuart Robertson Novice

           

          "smithbstl" wrote:
          I keep getting this returned via the debug page under my datamodel component. Why is the row unavailable? The wrapped data is some of the data returned via my query but the data model is not being displayed on the page. No exception is thrown.

          @Stateful
          @Name("addressListing")
          @Scope(ScopeType.SESSION)
          public class AddressListing implements mypackage.AddressListingLocal {
          
           @DataModel
           private List<StructureAddress> addresses;
          
           public String findAddresses() {
          
           if (address.getStreetName() != null) {
           //Find StructureAddress
           Query q = em.createQuery("Select a From StructureAddress a Where" +
           " (a.structureAddressPK.houseNumber = :houseNumber OR :houseNumber IS NULL) AND" +
           " (a.structureAddressPK.houseSuffix = :suffix OR :suffix IS NULL) AND" +
           " (a.nlc.streetDirection = :streetDirection OR :streetDirection IS NULL) AND" +
           " (lower(a.nlc.streetName) LIKE :street OR :street IS NULL)");
           q.setParameter("houseNumber",address.getHouseNumber());
           q.setParameter("suffix",address.getHouseSuffix());
           q.setParameter("streetDirection",address.getStreetDirection());
           q.setParameter("street",address.getStreetName().toLowerCase() + "%");
           addresses = q.getResultList();
           }
          
           return null;
           }
          }
          


          Here is the page

           <tr:table
           id="addresses"
           var="addressRow"
           value="#{addresses}"
          ...
           </tr:table>


          Looking at your page, you're binding the outjected #{addresses} to the table. And in the SFSB that field is in fact annoted properly. But I don't see in your bean where that value is initialized. How is findAddresses() called? And if it is, when is it? If it's called from the page rendering I wonder if this means the addresses list is populated AFTER Seam has outjected it. I think you may need a @Factory or @Create here.

          • 2. Re: @DataModel problems
            Brian Smith Apprentice

            Thanks for the reply, The findAddresses method is called by a submit button on the page. I am using Facelets and the table and form are not on the same xhtml file. I will try placing a Factory annotation here and see if that does the trick. Thanks again.

            • 3. Re: @DataModel problems
              Brian Smith Apprentice

              No luck, I tried adding a factory annotation but the findAddresses() method is just being called twice but still the DataModel is still not being rendered in the table.

              • 4. Re: @DataModel problems
                Fernando Montaño Expert

                Did you use @Factory("addresses") on your findAddresses() method?

                • 5. Re: @DataModel problems
                  Brian Smith Apprentice

                  Yes, I tried that already, it just resulted in the findAddresses() method being called twice, but the DataModel is still not being outjected properly. I am sure I am missing something trivial but not seeing it at the moment.

                  • 6. Re: @DataModel problems
                    Fernando Montaño Expert

                    This sample works. Maybe you can see (try) what is different with your code.

                    @Stateful
                    
                    @Scope(SESSION)
                    
                    @Name("messageManager")
                    
                    public class MessageManagerBean implements Serializable, MessageManager
                    
                    {
                    
                    
                    
                     @DataModel
                    
                     private List<Message> messageList;
                    
                    
                    
                     @DataModelSelection
                    
                     @Out(required=false)
                    
                     private Message message;
                    
                    
                    
                     @PersistenceContext(type=EXTENDED)
                    
                     private EntityManager em;
                    
                    
                    
                     @Factory("messageList")
                    
                     public void findMessages()
                    
                     {
                    
                     messageList = em.createQuery("select msg from Message msg order by msg.datetime desc").getResultList();
                    
                     }
                    
                    
                    
                     public void select()
                    
                     {
                    
                     if (message!=null) message.setRead(true);
                    
                     }
                    
                    
                    
                     public void delete()
                    
                     {
                    
                     if (message!=null)
                    
                     {
                    
                     messageList.remove(message);
                    
                     em.remove(message);
                    
                     message=null;
                    
                     }
                    
                     }
                    
                    
                    
                     @Remove @Destroy
                    
                     public void destroy() {}
                    
                    
                    
                    }
                    
                    
                    


                    • 7. Re: @DataModel problems
                      Brian Smith Apprentice

                      I have changed my code to reflect yours and still get the same result. I really prefer not to use a Factory method because the dataModel really should not be populated until the form is submitted. Basically this is an address locator where the user will input an address and a list of matching addresses is returned. I have tried this both with a Factory and without and still nothing. See my initial post and the Seam Debug page. Something weird is going on where I get the IllegalArgumentException and the Row is unavailable.

                      Thanks again for your help.

                      • 8. Re: @DataModel problems
                        Fernando Montaño Expert

                        Just wondering what could be wrong.

                        Some suggestions:
                        - Try a simple <h:dataTable>, maybe the error is throw by tr:dataTable component.
                        - This sounds silly, but tr:dataTable id="addresses" and value="${addresses}" could be causing some troubles? Try putting another id to the table (this shame me, but it is what I'll try because I don't know Trinidad).

                        If anything works, I agree with you this is really weird.

                        HTH.


                        • 9. Re: @DataModel problems
                          Brian Smith Apprentice

                          Thanks again,

                          I tried the h:dataTable a while ago, didn't help. I just tried changing the ID of the table, still nothing. Doesn't sound silly, I try weird stuff all the time. When you are out of ideas you start trying everything you can think.

                          • 10. Re: @DataModel problems
                            Fernando Montaño Expert

                            Hi smithbstl,

                            Because I was wondering about the weird problem, I tried to reproduce your code in my SEAM application, using @DataModel and filling it after a search criteria is entered. And all works fine.

                            Also I check what debug page returns and I get:

                            
                             class class org.jboss.seam.jsf.ListDataModel
                            dataModelListeners []
                            rowAvailable false
                            rowCount 22
                            rowData java.lang.IllegalArgumentException[row is unavailable]
                            rowIndex -1
                            wrappedData [com.jtp.app.domain.User@11be57f, com.jtp.app.domain.User@114e777, com.jtp.app.domain.User@1a6c368, com.jtp.app.domain.User@e48e45, com.jtp.app.domain.User@1e64a3b, com.jtp.app.domain.User@4f7537, com.jtp.app.domain.User@7413e8, com.jtp.app.domain.User@1125fe1, com.jtp.app.domain.User@14b43d, com.jtp.app.domain.User@199c55a, com.jtp.app.domain.User@1ebf5c, com.jtp.app.domain.User@164d75, com.jtp.app.domain.User@1224b90, com.jtp.app.domain.User@52ac68, com.jtp.app.domain.User@a6a7d2, com.jtp.app.domain.User@10d0630, com.jtp.app.domain.User@e1ed5b, com.jtp.app.domain.User@1a0353d, com.jtp.app.domain.User@1a40fff, com.jtp.app.domain.User@1245e75, com.jtp.app.domain.User@3c8db9, com.jtp.app.domain.User@1823918]
                            toString() org.jboss.seam.jsf.ListDataModel@1cbc5cb
                            
                            


                            As you can see in the debug the line java.lang.IllegalArgumentException[row is unavailable] is also presented for me. But nonetheless all is working fine for me. Seems like your problem is not precisely with @DataModel outjection.

                            Maybe the problem is residing anywhere else.



                            • 11. Re: @DataModel problems
                              Brian Smith Apprentice

                              I finally figured it out. It had to do with trying to make AJAX call via Trinidad. I don't have the specific cause nailed down yet but i was trying to use the partialSubmit feature of my submit button. Once I removed that all was fine. Thank you soooo much for your efforts and especially getting me to look elsewhere other than the DataModel. You're a champ! :)

                              -Brian