p:dataTable em várias p:Tab
Thursday, June 23, 2011 9:31:06 PM
[Postar qualquer coisa no blog tem sido uma tarefa pra leão... Nem Internet tenho em casa!].
Certo, depois de um longo inverno (humm... it's sounds familiar...) achei algo interessante a compartilhar...
A tempos atrás comecei a mexer com PrimeFaces 3.0.M1 (comecei usando o 2.2 e devido a alguns problemas atualizei a versão - e tive problemas novos). E ontem tive um problema MUIIIIITTTTOOOOO chato.
Descrição do problema
Possui um cadastro mestre/detalhe que está em duas abas de uma p:tabView. Em ambas as abas existe uma p:dataTable. Se eu populasse os dados da p:dataTable mestre, cujo bean possui uma lista do detalhe, ao mudar de aba, uma exceção era lançada "Property <nome> not found on type org.hibernate.collection.PersistentSet".
Codigo do mestre
public class Mestre
{
private Integer id;
private Set<Detalhe> detalhes;
public Integer getId()
{
return id;
}
public void setId(Integer id)
{
this.id = id;
}
public Set<Detalhe> getDetalhes()
{
return detalhes;
}
public void setDetalhes(Set<Detalhe> detalhes)
{
this.detalhes = detalhes;
}
}
Codigo do detalhe
public class Detalhe
{
private Integer id;
private Mestre mestre;
public Integer getId()
{
return id;
}
public void setId(Integer id)
{
this.id = id;
}
public Mestre getMestre()
{
return mestre;
}
public void setMestre(Mestre mestre)
{
this.mestre = mestre;
}
}
Mapeamento do mestre
<hibernate-mapping>
<class lazy="false" name="br.com.exemplo.metredetalhe.model.Mestre"
table="MESTRES">
<id name="id" type="java.lang.Integer" unsaved-value="null" column="id">
<generator class="sequence">
<param name="sequence">SEQ_ID_MESTRES</param>
</generator>
</id>
<set name="detalhes" lazy="false" inverse="true">
<key column="ID_MESTRES"/>
<one-to-many class="br.com.exemplo.metredetalhe.model.Detalhe"/>
</set>
</class>
</hibernate-mapping>
Código do Managed Bean
@ManagedBean(name="cadastroMestreDetalheScreen")
@ViewScoped
public class CadastroMestreDetalheScreen
{
private Mestre mestre;
private Detalhe detalhe;
...
}
A principio eu buscava os dados diretamente no Set do mestre, assim:
value="#{cadastroMestreDetalheScreen.mestre.detalhe}"
Porém, bastava pesquisar pelo mestre e trocar de aba que a exceção era disparada. Então resolvi criar uma lista no Managed Bean para tratar dessa p:dataTable, ficando:
Novo código do Managed Bean
@ManagedBean(name="cadastroMestreDetalheScreen")
@ViewScoped
public class CadastroMestreDetalheScreen
{
private Mestre mestre;
private Detalhe detalhe;
private ArrayList<Detalhe> listaDetalhes;
...
SuppressWarnings("unchecked")
public ArrayList<Detalhe> getListaDetalhes()
{
if((this.mestre.getDetalhes() != null) &&
(this.mestre.getDetalhes().size() > 0))
this.listaDetalhes = (ArrayList<Detalhe>)this.mestre.getDetalhes();
return listaDetalhes;
}
}
Novo código do xhtml
value="#{cadastroMestreDetalheScreen.listaDetalhes}"
Isso resolveu o problema! Agora porque isso? Porque o p:dataTable, que utiliza um DataModel, não suporta o Set, então fiz um cast para
ArrayList na camada de visualização, afinal de contas, no restante da aplicação não tenho problemas usando Set.
Lembrando-se que se utilizar annotations ou a tag <list> para mapear o atributo o problema não deve ocorrer.
Grande abraço!

