title: PrimeFaces, sort p:column based on a property of a property
body: <p>I'm working on a JSF 2.1 project using PrimeFaces, Spring and Hibernate.</p>
  
  <p>I have an entity called Provinces related to an entity called Region by a JoinColumn:</p>
  
  <pre><code>@Entity
  @Table(name = "PROVINCE")
  public class Province  {
  
      /* ... */        
  @ManyToOne
  @JoinColumn(name = "ID_REGION",nullable=false)
  public Region getRegion() {
      return region;
  }
  
  public void setRegion(Region region) {
      this.region = region;
  }
  
  @Column(name = "DESCRIPTION", nullable=false)
  public String getDescription() {
      return description;
  }
  
  public void setDescription(String description) {
      this.description = description;
  }
  
  }
  
  
  @Entity
  @Table(name = "REGION")
  public class Region  {
  
      /* ... */        
  @OneToMany(mappedBy = "region")
  public List&lt;Province&gt; getProvince() {
      return province;
  }
  
  public void setProvince(List&lt;Province&gt; province) {
      this.province = province;
  }
  
  @Column(name = "DESCRIPTION", nullable=false)
  public String getDescription() {
      return description;
  }
  
  public void setDescription(String description) {
      this.description = description;
  }
  
  }
  </code></pre>
  
  <p>On a JSF page I have a <code>p:dataTable</code> that shows a listing of the Provinces. Among the others I have a column showing the name of the region that the province belongs to.
  Something like:</p>
  
  <pre><code>        &lt;p:dataTable id="provincesDatatable"
          value="#{provinceMB.lazyProvinceViewModel}" 
          var="province"
          paginator="true" rows="15" lazy="true"
          emptyMessage="Nothing to see here, move along"
          paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"
          selection="#{admProvinceMB.selectedProvince}" selectionMode="single"
          rowsPerPageTemplate="5,10,15"&gt;
  
          &lt;p:column headerText="Province Name"
              sortBy="#{province.description}"&gt;
              &lt;h:outputText value="#{province.description}" /&gt;
          &lt;/p:column&gt;
  
          &lt;p:column headerText="Region Name"
              sortBy="#{province.region}"&gt;
              &lt;h:outputText value="#{province.region.description}" /&gt;
          &lt;/p:column&gt;
      &lt;/p:dataTable&gt;
  </code></pre>
  
  <p>(I'm omitting the backing bean and the LazyDataModel implementation as I think they aren't related to the problem, but if needed I can show them).
  This works fine, with the exception of sorting by region.</p>
  
  <p>The example above will order by region id, while I'd like to sort by region description, something like the following, which doesn't work.</p>
  
  <pre><code>&lt;p:column headerText="Region Name"
      sortBy="#{province.region.description}"&gt;
      &lt;h:outputText value="#{province.region.description}" /&gt;
  &lt;/p:column&gt;
  </code></pre>
  
  <p>Trying this will give me the error  org.hibernate.QueryException: could not resolve property: region.description of: my.package.entity.Province</p>
  
  <p>The only solution I could come up with is adding a transient field to <code>Province</code> called <code>regionDescription</code> which returns the description of the associated region, but it is a very ugly hack.
  Is there a better way to obtain this result ?</p>
  
  <p>Edit: the problem was elsewhere. here's the relevant code from the LazyDataModel</p>
  
  <pre><code>public List&lt;Province&gt; findLazyProvince(int startingAt, int maxPerPage,
          String sortField, SortOrder sortOrder, Map&lt;String, String&gt; filters)
  {
      Criteria crit = buildCriteria(filters);
  
      if (sortField != null &amp;&amp; !sortField.isEmpty()) {
          if (sortOrder.equals(SortOrder.ASCENDING)) {
              crit = crit.addOrder(Order.asc(sortField));
          } else {
              crit = crit.addOrder(Order.desc(sortField));
          }
      }
      crit = crit.setFirstResult(startingAt).setMaxResults(maxPerPage);
      return crit.list();
  }
  </code></pre>