13.3. Query objects

If we need a list of all Person instances in the database, we can use a Query object, like the following.
<framework:entity-query name="people" ejbql="select p from Person p"/>
We can use it from a JSF page:
<h1>List of people</h1> 
<h:dataTable value="#{people.resultList}" var="person"> 
  <h:column> 
    <s:link view="/editPerson.jsp" 
            value="#{person.firstName} #{person.lastName}"> 
      <f:param name="personId" value="#{person.id}"/> 
    </s:link> 
  </h:column> 
</h:dataTable>
If you require pagination support:
<framework:entity-query name="people" ejbql="select p from Person p" 
           order="lastName" max-results="20"/>
Use a page parameter to determine which page to display:
<pages> 
  <page view-id="/searchPerson.jsp"> 
    <param name="firstResult" value="#{people.firstResult}"/> 
  </page> 
</pages>
The JSF code for pagination control is slightly verbose, but manageable:
<h1>Search for people</h1> 
<h:dataTable value="#{people.resultList}" var="person"> 
  <h:column>
   
    <s:link view="/editPerson.jsp" 
            value="#{person.firstName} #{person.lastName}">       
      <f:param name="personId" value="#{person.id}"/> 
    </s:link>
     
  </h:column>
   
</h:dataTable>
 
<s:link view="/search.xhtml" rendered="#{people.previousExists}" 
        value="First Page"> 
  <f:param name="firstResult" value="0"/> 
</s:link>
 
<s:link view="/search.xhtml" rendered="#{people.previousExists}" 
        value="Previous Page"> 
  <f:param name="firstResult" value="#{people.previousFirstResult}"/> 
</s:link>
 
<s:link view="/search.xhtml" rendered="#{people.nextExists}" 
        value="Next Page"> 
  <f:param name="firstResult" value="#{people.nextFirstResult}"/> 
</s:link>
 
<s:link view="/search.xhtml" rendered="#{people.nextExists}" 
        value="Last Page"> 
  <f:param name="firstResult" value="#{people.lastFirstResult}"/> 
</s:link>
Real search screens let the user enter optional search criteria to narrow the list of returned results. The Query object lets you specify optional restrictions to support this usecase:
<component name="examplePerson" class="Person"/> 
<framework:entity-query name="people" ejbql="select p from Person p" 
           order="lastName" max-results="20"> 
  <framework:restrictions> 
  
    <value>
      lower(firstName) like lower(concat(#{examplePerson.firstName},'%&'))
    </value>
    
    <value>
      lower(lastName) like lower(concat(#{examplePerson.lastName},'%&'))
    </value>
     
  </framework:restrictions> 
</framework:entity-query>
Notice the use of an "example" object.
<h1>Search for people</h1> 
<h:form>
 
  <div>
    First name: <h:inputText value="#{examplePerson.firstName}"/>
  </div>
   
  <div>
    Last name: <h:inputText value="#{examplePerson.lastName}"/>
  </div>
   
  <div>
    <h:commandButton value="Search" action="/search.jsp"/>
  </div>
   
</h:form>
 
<h:dataTable value="#{people.resultList}" var="person"> 
  <h:column> 
    <s:link view="/editPerson.jsp" 
       value="#{person.firstName} #{person.lastName}"> 
      <f:param name="personId" value="#{person.id}"/> 
    </s:link> 
  </h:column>  
</h:dataTable>
To refresh the query when the underlying entities change, we observe the org.jboss.seam.afterTransactionSuccess event:
<event type="org.jboss.seam.afterTransactionSuccess"> 
  <action execute="#{people.refresh}" /> 
</event>
Or, to refresh the query when the person entity is persisted, updated or removed through PersonHome:
<event type="org.jboss.seam.afterTransactionSuccess.Person"> 
  <action execute="#{people.refresh}" /> 
</event>
Unfortunately, Query objects do not work well with join fetch queries. We do not recommend using pagination with these queries. You will need to implement your own method of total result number calculation by overriding getCountEjbql().
All of the examples in this section have shown re-use via configuration. It is equally possibly to re-use via extension: