2013-07-05 2 views
0

Я работаю над проектом JSF 2.1 с использованием PrimeFaces, Spring и Hibernate.PrimeFaces, sort p: column на основе свойства свойства

Я Субъект называется Регионы, связанные с лица называется область на JoinColumn:

@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<Province> getProvince() { 
    return province; 
} 

public void setProvince(List<Province> province) { 
    this.province = province; 
} 

@Column(name = "DESCRIPTION", nullable=false) 
public String getDescription() { 
    return description; 
} 

public void setDescription(String description) { 
    this.description = description; 
} 

} 

на странице JSF У меня есть p:dataTable, который показывает список провинций. Среди других у меня есть столбец с названием региона, к которому принадлежит провинция. Что-то вроде:

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

     <p:column headerText="Province Name" 
      sortBy="#{province.description}"> 
      <h:outputText value="#{province.description}" /> 
     </p:column> 

     <p:column headerText="Region Name" 
      sortBy="#{province.region}"> 
      <h:outputText value="#{province.region.description}" /> 
     </p:column> 
    </p:dataTable> 

(я опускаю подпирая боб и реализацию LazyDataModel, как я думаю, что они не связаны с этой проблемой, но в случае необходимости я могу показать их). Это прекрасно работает, за исключением сортировки по регионам.

Пример, указанный выше, будет заказывать по региону id, в то время как я хотел бы отсортировать по региону описание, что-то вроде следующего, что не работает.

<p:column headerText="Region Name" 
    sortBy="#{province.region.description}"> 
    <h:outputText value="#{province.region.description}" /> 
</p:column> 

Попытка это даст мне org.hibernate.QueryException ошибку: не удалось разрешить свойство: region.description из: my.package.entity.Province

Единственное решение, которое я мог придумать это добавление переходного поля в Province под названием regionDescription, которое возвращает описание связанной области, но это очень уродливый взломать. Есть ли лучший способ получить этот результат?

Редактировать: проблема была в другом месте. здесь соответствующий код из LazyDataModel

public List<Province> findLazyProvince(int startingAt, int maxPerPage, 
     String sortField, SortOrder sortOrder, Map<String, String> filters) 
{ 
    Criteria crit = buildCriteria(filters); 

    if (sortField != null && !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(); 
} 
+0

Поскольку вы используете LazyDataModel, ваш код должен заботиться о сортировке. – perissf

+0

Ах да, вы правы. Я имею в виду, это то, что я делаю, но и это проблема. Спасибо, спасибо. –

ответ

1

В конце концов, это была глупая ошибка с моей стороны: поле сортировки (в моем случае «region.description») передаются без изменений в виде строки в LazyDataModel, так мой долг - правильно обработать его в коде, добавив псевдоним.

Так выше код должен стать чем-то вроде

public List<Province> findLazyProvince(int startingAt, int maxPerPage, 
    String sortField, SortOrder sortOrder, Map<String, String> filters) 
{ 
    Criteria crit = buildCriteria(filters); 

    if (sortField != null && sortField.equals("region.description")) { 
     crit.createAlias("region", "region"); 
    } 
    if (sortField != null && !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(); 
} 
Смежные вопросы