4 Replies Latest reply on Mar 11, 2007 7:03 AM by Christian Bauer

    @DataModel == ListDataModel ???

    Danijel Jevtic Novice

      Hello everyone,
      I have a question regarding the @DataModel annotation regarding large result sets (> 100.000):
      When I do a getResultList on the entityManager and I annotate the List with @DataModel, are all records fetched at once?
      I am playing with the datascroller tag of richfaces and it looks to me if, even when I set the rows property to 20, still all records are fetched from the database.
      Is there a way to just fetch the amount of records, that I will actually see on the page using seam or do I have to implement pagination completely by myself?
      Can somebody clarify please...

        • 1. Re: @DataModel == ListDataModel ???
          Norman Richards Master

          @DataModel simply wraps the data in an appropriate JSF data model. (ListDataModel for a List, as an example) There would no link to your query or any page state unless you created it yourself.

          • 3. Re: @DataModel == ListDataModel ???
            Danijel Jevtic Novice

            Thanks, I decided to implement my own "PersistableList" and my own @PersistableDataModel.
            Basically the List fetches the objects from a database the first time they are required.
            It works great now, even supports filtering and RecordsPerPage settings.
            Thanks for all the tipps.

            Regards,
            dj

            • 4. Re: @DataModel == ListDataModel ???
              Christian Bauer Master

              Here is some code I use for paginating through large lists:

              @Name("userSearch")
              @Scope(ScopeType.CONVERSATION)
              public class UserSearch implements Serializable {
              
               @In
               private UserDAO userDAO;
              
               @In
               private FacesMessages facesMessages;
              
               private User exampleUser;
               private String orderByProperty;
               private boolean orderDescending;
               private String[] ignoreProperties;
               private int rowCount;
               private int maxPageSize;
               private int pageSize;
               private int page;
              
               @DataModel
               private List<User> usersList;
              
               @Create
               public void initialize() {
               pageSize = 10;
               maxPageSize = 1000;
               exampleUser = new User();
               orderByProperty = "username";
               orderDescending = false;
               ignoreProperties = new String[]{"passwordHash", "activated", "createdOn"};
               }
              
               public void find() {
               page = 0;
               queryRowCount();
               if (rowCount != 0) queryUsers();
               }
              
               public void nextPage() {
               page++;
               queryUsers();
               }
              
               public void previousPage() {
               page--;
               queryUsers();
               }
              
               public void firstPage() {
               page = 0;
               queryUsers();
               }
              
               public void lastPage() {
               page = (rowCount / pageSize);
               if (rowCount % pageSize == 0) page--;
               queryUsers();
               }
              
               private void queryRowCount() {
               rowCount = userDAO.getRowCountByExample(exampleUser, ignoreProperties);
               if (rowCount == 0) {
               facesMessages.addFromResourceBundleOrDefault(
               FacesMessage.SEVERITY_INFO,
               "noUserFound",
               "No user with given attributes was found, please try again."
               );
               }
               }
              
               private void queryUsers() {
               usersList = userDAO.findByExample(exampleUser, orderByProperty, orderDescending, page * pageSize, pageSize, ignoreProperties);
               }
              
               public boolean isNextPageAvailable() {
               return usersList != null && rowCount > ((page * pageSize) + pageSize);
               }
              
               public boolean isPreviousPageAvailable() {
               return usersList != null && page > 0;
               }
               public int getPageSize() {
               return pageSize;
               }
              
               public void setPageSize(int pageSize) {
               this.pageSize = pageSize > maxPageSize ? maxPageSize : pageSize; // Prevent tampering
               }
              
               public int getRowCount() {
               return rowCount;
               }
              
               public User getExampleUser() {
               return exampleUser;
               }
              
               public void setExampleUser(User exampleUser) {
               this.exampleUser = exampleUser;
               }
              
               public String getOrderByProperty() {
               return orderByProperty;
               }
              
               public boolean isOrderDescending() {
               return orderDescending;
               }
              
               public void sortBy(String propertyName) {
               orderByProperty = propertyName;
               orderDescending = !isOrderDescending(); // Switch between ASC and DESC
               page = 0; // Reset to first page
               queryUsers();
               }
              
              }
              


              @Name("userDAO")
              @AutoCreate
              @Transactional
              public class UserDAO {
              
               @In
               protected EntityManager entityManager;
              
               public List<User> findByExample(User exampleUser, String orderByProperty, boolean orderDescending,
               int firstResult, int maxResults, String... ignoreProperty) {
               Criteria crit = prepareExampleCriteria(exampleUser, orderByProperty, orderDescending, ignoreProperty);
               crit.setFirstResult(firstResult).setMaxResults(maxResults);
               return (List<User>)crit.list();
               }
              
               public int getRowCountByExample(User exampleUser, String... ignoreProperty) {
              
               Criteria crit = prepareExampleCriteria(exampleUser, null, false, ignoreProperty);
               ScrollableResults cursor = crit.scroll();
               cursor.last();
               int count = cursor.getRowNumber() + 1;
               cursor.close();
               return count;
               }
              
               private Criteria prepareExampleCriteria(User exampleUser, String orderByProperty, boolean orderDescending, String... ignoreProperty) {
               entityManager.joinTransaction();
              
               Example example = Example.create(exampleUser).enableLike(MatchMode.ANYWHERE).ignoreCase();
              
               for (String s : ignoreProperty) example.excludeProperty(s);
              
               Session session = (Session)entityManager.getDelegate();
              
               Criteria crit = session.createCriteria(User.class).add(example);
               if (orderByProperty != null)
               crit.addOrder( orderDescending ? Order.desc(orderByProperty) : Order.asc(orderByProperty) );
              
               return crit.setResultTransformer(new DistinctRootEntityResultTransformer());
               }
              
              }
              


               <h:form id="main">
              
               <div class="form" id="userSearchControl">
              
               <h:panelGrid columns="6" styleClass="formTable"
               headerClass="formHead" footerClass="formFooter"
               columnClasses="entryColumn,entryColumn,entryColumn,entryColumn,entryColumn,entryColumn"
               cellpadding="0" cellspacing="0" border="0">
              
               <f:facet name="header">
               <h:outputText value="Search members"/>
               </f:facet>
              
               <h:panelGroup>
               <h:outputText styleClass="label" value="Username:"/>
               <h:inputText styleClass="input" id="username" value="#{userSearch.exampleUser.username}" maxlength="25" size="10" tabindex="1"/>
               </h:panelGroup>
              
               <h:panelGroup>
               <h:outputText styleClass="label" value="First name:"/>
               <h:inputText styleClass="input" id="firstname" value="#{userSearch.exampleUser.firstname}" maxlength="25" size="10" tabindex="2"/>
               </h:panelGroup>
              
               <h:panelGroup>
               <h:outputText styleClass="label" value="Last name:"/>
               <h:inputText styleClass="input" id="lastname" value="#{userSearch.exampleUser.lastname}" maxlength="25" size="10" tabindex="3"/>
               </h:panelGroup>
              
               <h:panelGroup>
               <h:outputText styleClass="label" value="E-mail:"/>
               <h:inputText styleClass="input" id="email" value="#{userSearch.exampleUser.email}" maxlength="25" size="10" tabindex="4"/>
               </h:panelGroup>
              
               <h:panelGroup>
               <h:outputLabel styleClass="label" for="pageSize">Show:</h:outputLabel>
               <h:selectOneMenu styleClass="input" value="#{userSearch.pageSize}" id="pageSize" tabindex="5">
               <f:selectItem itemLabel="5" itemValue="5"/>
               <f:selectItem itemLabel="10" itemValue="10"/>
               <f:selectItem itemLabel="20" itemValue="20"/>
               </h:selectOneMenu>
               </h:panelGroup>
              
               <h:commandLink id="find" styleClass="button"
               action="#{userSearch.find()}"
               tabindex="6" accesskey="F"><span class="buttonLabel"><u>F</u>ind</span></h:commandLink>
              
               <f:facet name="footer">
                
               </f:facet>
              
               </h:panelGrid>
              
               </div>
              
               <h:panelGrid columns="5" styleClass="pager"
               columnClasses="pagerIconColumn,pagerIconColumn,pagerTextColumn,pagerIconColumn,pagerIconColumn"
               cellpadding="0" cellspacing="0" border="0"
               rendered="#{userSearch.rowCount > 0}">
              
               <h:commandLink action="#{userSearch.firstPage()}" rendered="#{userSearch.previousPageAvailable}" tabindex="7">
               <h:graphicImage value="/themes/#{globalPrefs.themeName}/img/page.first.gif" width="13" height="11"/>
               </h:commandLink>
               <h:graphicImage value="/themes/#{globalPrefs.themeName}/img/blank.gif" width="13" height="11"
               rendered="#{!userSearch.previousPageAvailable}"/>
              
               <h:commandLink action="#{userSearch.previousPage()}" rendered="#{userSearch.previousPageAvailable}" tabindex="7">
               <h:graphicImage value="/themes/#{globalPrefs.themeName}/img/page.previous.gif" width="13" height="11"/>
               </h:commandLink>
               <h:graphicImage value="/themes/#{globalPrefs.themeName}/img/blank.gif" width="13" height="11"
               rendered="#{!userSearch.previousPageAvailable}"/>
              
               <h:outputText value="Found: #{userSearch.rowCount} member(s)"/>
              
               <h:commandLink action="#{userSearch.nextPage()}" rendered="#{userSearch.nextPageAvailable}" tabindex="7">
               <h:graphicImage value="/themes/#{globalPrefs.themeName}/img/page.next.gif" width="13" height="11"/>
               </h:commandLink>
               <h:graphicImage value="/themes/#{globalPrefs.themeName}/img/blank.gif" width="13" height="11"
               rendered="#{!userSearch.nextPageAvailable}"/>
              
               <h:commandLink action="#{userSearch.lastPage()}" rendered="#{userSearch.nextPageAvailable}" tabindex="7">
               <h:graphicImage value="/themes/#{globalPrefs.themeName}/img/page.last.gif" width="13" height="11"/>
               </h:commandLink>
               <h:graphicImage value="/themes/#{globalPrefs.themeName}/img/blank.gif" width="13" height="11"
               rendered="#{!userSearch.nextPageAvailable}"/>
              
               </h:panelGrid>
              
               <h:dataTable id="userTable" var="u"
               value="#{usersList}"
               rendered="#{usersList.rowCount >0}"
               styleClass="datatable"
               headerClass="sortableHeader"
               columnClasses="twentyPercentColumn,twentyPercentColumn,twentyPercentColumn,defaultColumn,defaultColumn"
               rowClasses="rowOdd,rowEven"
               cellpadding="0" cellspacing="0" border="0">
              
               <h:column>
               <f:facet name="header">
               <h:commandLink action="#{userSearch.sortBy('username')}" tabindex="8">
               <h:graphicImage value="/themes/#{globalPrefs.themeName}/img/sortindicator.up.gif" width="8" height="8"
               rendered="#{!userSearch.orderDescending and userSearch.orderByProperty == 'username'}"/>
               <h:graphicImage value="/themes/#{globalPrefs.themeName}/img/sortindicator.down.gif" width="8" height="8"
               rendered="#{userSearch.orderDescending and userSearch.orderByProperty == 'username'}"/>
               Username
               </h:commandLink>
               </f:facet>
               <s:link view="/userAccount.xhtml" value="#{u.username}" tabindex="13" propagation="nest">
               <f:param name="userId" value="#{u.id}"/>
               </s:link>
               </h:column>
              
               <h:column>
               <f:facet name="header">
               <h:commandLink action="#{userSearch.sortBy('firstname')}" tabindex="9">
               <h:graphicImage value="/themes/#{globalPrefs.themeName}/img/sortindicator.up.gif" width="8" height="8"
               rendered="#{!userSearch.orderDescending and userSearch.orderByProperty == 'firstname'}"/>
               <h:graphicImage value="/themes/#{globalPrefs.themeName}/img/sortindicator.down.gif" width="8" height="8"
               rendered="#{userSearch.orderDescending and userSearch.orderByProperty == 'firstname'}"/>
               First name
               </h:commandLink>
               </f:facet>
               #{u.firstname}
               </h:column>
              
               <h:column>
               <f:facet name="header">
               <h:commandLink action="#{userSearch.sortBy('lastname')}" tabindex="10">
               <h:graphicImage value="/themes/#{globalPrefs.themeName}/img/sortindicator.up.gif" width="8" height="8"
               rendered="#{!userSearch.orderDescending and userSearch.orderByProperty == 'lastname'}"/>
               <h:graphicImage value="/themes/#{globalPrefs.themeName}/img/sortindicator.down.gif" width="8" height="8"
               rendered="#{userSearch.orderDescending and userSearch.orderByProperty == 'lastname'}"/>
               Last name
               </h:commandLink>
               </f:facet>
               #{u.lastname}
               </h:column>
              
               <h:column>
               <f:facet name="header">
               <h:commandLink action="#{userSearch.sortBy('email')}" tabindex="11">
               <h:graphicImage value="/themes/#{globalPrefs.themeName}/img/sortindicator.up.gif" width="8" height="8"
               rendered="#{!userSearch.orderDescending and userSearch.orderByProperty == 'email'}"/>
               <h:graphicImage value="/themes/#{globalPrefs.themeName}/img/sortindicator.down.gif" width="8" height="8"
               rendered="#{userSearch.orderDescending and userSearch.orderByProperty == 'email'}"/>
               E-mail address
               </h:commandLink>
               </f:facet>
               #{u.email}
               </h:column>
              
               <h:column>
               <f:facet name="header">
               <h:commandLink action="#{userSearch.sortBy('createdOn')}" tabindex="12">
               <h:graphicImage value="/themes/#{globalPrefs.themeName}/img/sortindicator.up.gif" width="8" height="8"
               rendered="#{!userSearch.orderDescending and userSearch.orderByProperty == 'createdOn'}"/>
               <h:graphicImage value="/themes/#{globalPrefs.themeName}/img/sortindicator.down.gif" width="8" height="8"
               rendered="#{userSearch.orderDescending and userSearch.orderByProperty == 'createdOn'}"/>
               Joined on
               </h:commandLink>
               </f:facet>
               <h:outputText value="#{u.createdOn}">
               <f:convertDateTime type="both"/>
               </h:outputText>
               </h:column>
              
               </h:dataTable>
              
              
               </h:form>