Primefaces - Sorting entre persistentes com relacionamento @ManyToOne

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

seus sorts estão errado você tem que coloca #{conta.responsavel} exemplo da primeira coluna

Tiago, os sortings nas colunas estão funcionando, se eu colocar na coluna de Indústria a lista ordenada pela mesma é retornada vazia.

As propriedades de sortBy estão de acordo com o showcase do primefaces, conforme o link abaixo:

http://www.primefaces.org/showcase-labs/ui/datatableSorting.jsf

Obrigado brow, mas deve ser outra coisa, eu estou disconfiado que seja na maneira de implementar o sorting no LazyDataModel.
Estou vendo se é isto!

Valeu!
Atenciosamente,
Jesus