4 Replies Latest reply on Mar 11, 2007 7:03 AM by christian.bauer

    @DataModel == ListDataModel ???

    dajevtic

      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 ???

          @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.

          • 2. Re: @DataModel == ListDataModel ???
            fernando_jmt

            In order to load data on demand you can take a look at:

            Using Seam Framework:
            http://docs.jboss.com/seam/1.2.0.GA/reference/en/html/framework.html#d0e5791

            Using custom DataModel
            http://wiki.apache.org/myfaces/WorkingWithLargeTables


            HTH.

            • 3. Re: @DataModel == ListDataModel ???
              dajevtic

              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

                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>