Bom dia Galera!
Estou com um problema ao tentar realizar o sorting na coluna que exibe o relacionamento entre Conta e Indústria no datatable do primefaces. Está salvando, alterando e a exclusão não precisa ser cascade, e a lista exibe normalmente, inclusive o sorting funciona para as outras colunas.
Na web, no GUJ e no stackoverflow eu não encontrei tópico com o mesmo problema aparentemente.
No GUIDE do primefaces eu encontrei uma opção de realizar o sorting através de um método, assim:
<p:dataTable var="car" value="#{carBean.cars}" dynamic="true">
<p:column sortBy="model" sortFunction="#{carBean.sortByModel}"
headerText="Model">
<h:outputText value="#{car.model}" />
</p:column>
...more columns
</p:dataTable>
Dúvida
Antes de implementar, quero saber se vocês já passaram por isso e se existe outro caminho mais rápido, pois haverão outros relacionamentos também.
Erro
Seguem os Códigos.
Mapeamento.
Conta.java
@Entity
@Table(name = "CONTA")
public class Conta implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="CONTA_ID")
private Integer id;
.
.
.
@ManyToOne
@JoinColumn(name = "CONTA_INDUSTRIA_ID", referencedColumnName = "INDUSTRIA_ID")
private Industria industria;
.
.
.
}
Industria.java
@Entity
@Table(name = "INDUSTRIA")
public class Industria implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="INDUSTRIA_ID")
private Integer id;
.
.
.
@OneToMany(mappedBy = "industria")
private Set<Conta> contas;
.
.
.
}
Datatable
<h:form id="form" onLoad="reset()">
<p:dataTable id="dataTable" var="conta"
value="#{contaBean.contaLazyModel}"
emptyMessage="Registros não encontrado(s)." paginator="true"
rows="10" filterEvent="enter"
selection="#{contaBean.contaSelecionado}"
selectionMode="single"
rowKey="#{conta.id}"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
lazy="true" rowsPerPageTemplate="10,15,50">
<f:facet name="header">
Lista de Contas
</f:facet>
<p:ajax event="rowSelect" listener="#{contaBean.onRowSelect}"
update=":accountDetailForm:display"
oncomplete="PF('detalheDialog').show()" />
<p:column headerText="Nome" sortBy="nome" id="nome"
filterMatchMode="contains">
#{conta.nome}
</p:column>
<p:column headerText="Responsável" sortBy="responsavel"
id="responsavel">
#{conta.responsavel}
</p:column>
<p:column headerText="Status" sortBy="status" id="status">
#{conta.status}
</p:column>
<p:column headerText="Solução Corrente"
sortBy="solucaoCorrente" id="solucaoCorrente">
#{conta.solucaoCorrente}
</p:column>
<p:column headerText="Status Sol. Corrente"
sortBy="statusSolucaoCorrente" id="statusSolucaoCorrente">
#{conta.statusSolucaoCorrente}
</p:column>
<p:column headerText="Localidade" sortBy="localidade"
id="localidade">
#{conta.localidade}
</p:column>
<p:column headerText="Telefone" sortBy="telefone" id="telefone">
#{conta.telefone}
</p:column>
<p:column headerText="Website" sortBy="website" id="website">
#{conta.website}
</p:column>
<p:column headerText="Indústria" sortBy="industria.descricao" id="industria">
#{conta.industria.descricao}
</p:column>
<p:column headerText="Excluir" width="0">
<center>
<h:commandLink actionListener="#{contaBean.excluir}">
<f:param name="inc" value="#{conta}" />
<h:graphicImage title="excluir" library="icons"
name="delete_16x16.png" />
</h:commandLink>
</center>
</p:column>
<f:facet name="footer">
<p:commandButton value="Nova Conta"
oncomplete="novoDialog.show()" icon="ui-icon-star"
title="Criando uma nova conta" />
</f:facet>
</p:dataTable>
</h:form>
ContaLazySorter.java
public class ContaLazySorter extends LazySorterCrm<Conta> {
public ContaLazySorter(String sortField, SortOrder sortOrder) {
super(sortField, sortOrder);
}
}
LazySorterBase.java
public abstract class LazySorterCrm<T> implements Comparator<T> {
protected String sortField;
protected SortOrder sortOrder;
public LazySorterCrm(String sortField, SortOrder sortOrder) {
this.sortField = sortField;
this.sortOrder = sortOrder;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public int compare(T object1, T object2){
try {
Field field1 = object1.getClass().getDeclaredField(this.sortField);
Field field2 = object2.getClass().getDeclaredField(this.sortField);
field1.setAccessible(true);
field2.setAccessible(true);
Object value1 = field1.get(object1);
Object value2 = field2.get(object2);
int value = ((Comparable)value1).compareTo(value2);
return SortOrder.ASCENDING.equals(sortOrder) ? value : -1 * value;
}
catch(Exception e) {
throw new RuntimeException();
}
}
}
ContaLazyDataModel.java
public class ContaLazyDataModel extends LazyDataModelBase<Conta> {
/**
*
*/
private static final long serialVersionUID = 2199148967864739076L;
public ContaLazyDataModel(IFacade<Conta> facade) {
super(facade);
}
/**
* Lazy loading conta list with sorting ability
* @param first
* @param pageSize
* @param sortField
* @param sortOrder
* @param filters
* @return List<Conta>
*/
@Override
public List<Conta> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String,String> filters) {
datasource = facade.findWithNamedQuery(Conta.ALL, first, first + pageSize);
// Se o campo ordenado não for nulo, então ordenaremos o campo de acordo com os parâmetros sortfield e sortOrder.
if(sortField != null) {
Collections.sort(datasource, new ContaLazySorter(sortField, sortOrder));
}
setRowCount(facade.countTotalRecord(Conta.TOTAL));
return datasource;
}
/**
* Gets the conta object's primary key
* @param conta
* @return Object
*/
@Override
public Object getRowKey(Conta entity) {
return (entity != null && entity.getId() != null) ? entity.getId().toString() : null;
}
}
LazyDataModelBase.java
public abstract class LazyDataModelBase<T> extends LazyDataModel<T> implements SelectableDataModel<T>,
Serializable {
/**
*
*/
private static final long serialVersionUID = -1653116258907606654L;
protected int pageSize;
protected int rowIndex;
protected int rowCount;
protected List<T> datasource;
protected IFacade<T> facade;
public LazyDataModelBase(IFacade<T> facade) {
this.facade = facade;
}
public abstract List<T> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String,String> filters);
public abstract Object getRowKey(T entity);
/**
* Checks if the row is available
* @return boolean
*/
@Override
public boolean isRowAvailable() {
if(datasource == null)
return false;
int index = rowIndex % pageSize ;
return index >= 0 && index < datasource.size();
}
/**
* Returns the conta object at the specified position in datasource.
* @return
*/
@Override
public T getRowData() {
if(datasource == null)
return null;
int index = rowIndex % pageSize;
if(index > datasource.size()){
return null;
}
return datasource.get(index);
}
/*
* ===== Getters and Setters of LazyDataModel fields
*/
/**
*
* @param pageSize
*/
@Override
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
/**
* Returns page size
* @return int
*/
@Override
public int getPageSize() {
return pageSize;
}
/**
* Returns current row index
* @return int
*/
@Override
public int getRowIndex() {
return this.rowIndex;
}
/**
* Sets row index
* @param rowIndex
*/
@Override
public void setRowIndex(int rowIndex) {
this.rowIndex = rowIndex;
}
/**
* Sets row count
* @param rowCount
*/
@Override
public void setRowCount(int rowCount) {
this.rowCount = rowCount;
}
/**
* Returns row count
* @return int
*/
@Override
public int getRowCount() {
return this.rowCount;
}
/**
* Sets wrapped data
* @param list
*/
@SuppressWarnings("unchecked")
@Override
public void setWrappedData(Object list) {
this.datasource = ((List<T>) list);
}
/**
* Returns wrapped data
* @return
*/
@Override
public Object getWrappedData() {
return datasource;
}
}
Obrigado desde já!
Cya!
Jesus