Fórum listar as entidades envolvidas no relacionamento muitos pata muitos #414758
29/03/2012
0
Veja o sql
StringBuffer sql = new StringBuffer();
sql.append(select p.*,e.* from polo p join polo_empresa pe );
sql.append( on(p.id_polo = pe.id_polo) join );
sql.append( empresa e on(e.id_empresa = pe.id_empresa));
SQLQuery query = this.session.createSQLQuery(sql.toString());
query.addEntity(e,Empresa.class);
query.addEntity(p,Polo.class);
return query.list();
______________________________________
classe PK
@Embeddable
public class PoloEmpresaPK implements Serializable{
private static final long serialVersionUID = 2145230426707580106L;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name=id_polo)
private Polo polo;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = id_empresa)
private Empresa empresa;
public Polo getPolo() {
return polo;
}
public void setPolo(Polo polo) {
this.polo = polo;
}
public Empresa getEmpresa() {
return empresa;
}
public void setEmpresa(Empresa empresa) {
this.empresa = empresa;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((empresa == null) ? 0 : empresa.hashCode());
result = prime * result + ((polo == null) ? 0 : polo.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
PoloEmpresaPK other = (PoloEmpresaPK) obj;
if (empresa == null) {
if (other.empresa != null)
return false;
} else if (!empresa.equals(other.empresa))
return false;
if (polo == null) {
if (other.polo != null)
return false;
} else if (!polo.equals(other.polo))
return false;
return true;
}
_______________________________
Classe polo empresa
@Entity
@Table(name=polo_empresa)
public class PoloEmpresa implements Serializable {
/**
*
*/
private static final long serialVersionUID = 6176645767173588871L;
@EmbeddedId
private PoloEmpresaPK chaveComposta;
public PoloEmpresaPK getChaveComposta() {
return chaveComposta;
}
public void setChaveComposta(PoloEmpresaPK chaveComposta) {
this.chaveComposta = chaveComposta;
}
________________
classe polo
@Entity
@Table(name=polo)
@SequenceGenerator(name=seq_polo,sequenceName=seq_polo)
public class Polo implements Serializable{
private static final long serialVersionUID = -6638112313261035555L;
@Id
@GeneratedValue(generator=seq_polo,strategy=GenerationType.AUTO)
@Column(name=id_polo)
private Integer codigoPolo;
@Column(name=nome,length=40)
private String nome ;
@ManyToMany(fetch=FetchType.LAZY)
@JoinTable(name=polo_empresa,joinColumns={@JoinColumn(name=id_polo)},
inverseJoinColumns={@JoinColumn(name=id_empresa)})
@Cascade(CascadeType.SAVE_UPDATE)
@org.hibernate.annotations.ForeignKey(name = fk_polo_empresa)
//private Set<Empresa> empresa = new HashSet<Empresa>();
private Collection<Empresa> empresaList;
__________________________
classe empresa
@Entity
@Table(name=empresa)
@SequenceGenerator(name=seq_empresa,sequenceName=seq_empresa)
public class Empresa implements Serializable{
private static final long serialVersionUID = 498803724556690440L;
@Id
@GeneratedValue(generator=seq_empresa,strategy= GenerationType.AUTO)
@Column(name=id_empresa)
private Integer codigoEmpresa;
@Column(name=nome,length=40)
private String nome ;
@Column(name=nome_fan,length=20)
private String nomeFantasia ;
Jose Boas
Curtir tópico
+ 0Posts
29/03/2012
Davi Costa
@ManyToMany(fetch=FetchType.LAZY)
@JoinTable(name=polo_empresa,joinColumns={@JoinColumn(name=id_polo)},
inverseJoinColumns={@JoinColumn(name=id_empresa)})
@Cascade(CascadeType.SAVE_UPDATE)
@org.hibernate.annotations.ForeignKey(name = fk_polo_empresa)
//private Set<Empresa> empresa = new HashSet<Empresa>();
private Collection<Empresa> empresaList;
nem é para tem a entidade PoloEmpresa, sério mesmo não precisa nem dela nem de PoloEmpresaPK, pode deletar sem medo de ser feliz.
Basta vc fazer um select normal em polo que sempre vai trazer as empresas juntos, pode acreditar.
Porém como está lazy o relacionamento vai dar lazyException quando vc der um getEmpresaList(), caso não tenha nenhuma transação aberta. A solução é remove o lazy na sua aplicação seja muito requerido a lista de empresas do polo, para ele num select só sempre trazer as empresas do polo (na minha opnião melhor opção), ou sempre que for dar esse getEmpresaList() em polo fazer uma consulta no banco paar trazer as empresas pertences a esse polo.
Mais uma dica que tal deixar assim o mapeamento:
@ManyToMany(fetch=FetchType.EAGER)
@JoinTable(name=polo_empresa,joinColumns={@JoinColumn(name=id_polo)},
inverseJoinColumns={@JoinColumn(name=id_empresa)})
//@Cascade(CascadeType.SAVE_UPDATE)
@Fetch(FetchMode.SUBSELECT)
//@org.hibernate.annotations.ForeignKey(name = fk_polo_empresa)
//private Set<Empresa> empresa = new HashSet<Empresa>();
private Collection<Empresa> empresaList;
Observou o trecho comentado e a adição de subselect... esse cascade também é desnecessário se vc seguir minhas dicas, ele já vai atualizar por cascata direitinho sempre que fizer isso. Mas sóvai funcionar se vc seguir todos os passos mesmo removendo PoloEmpresa e PoloEmpresaPK, o JPA já vai fazer isso tudo para vc inclusive se vc gerar o banco via aplicação vai perceber que mesmo sem ter essas classes no java (PoloEmpresa e PoloEmpresaPK) o banco vai estar com essa tabela criada lá ele entende esse mapeamento e faz a mágica @JoinTable(name=polo_empresa,joinColumns={@JoinColumn(name=id_polo)},
inverseJoinColumns={@JoinColumn(name=id_empresa)}).
espero ter ajudado
att Davi
Gostei + 0
29/03/2012
Jose Boas
assim polo.empresaList.nomeFantasia da erro no nomeFantasia que não identificou, se não fosse uma collection
daria certo.
<p:column style=width:40px sortBy=#{polo.empresaList}>
<f:facet name=header>Nome Polo</f:facet>
<h:outputText value=#{polo.empresaList.nomeFantasia}/>
</p:column>
Gostei + 0
29/03/2012
Davi Costa
ai na tabela vc cria um var=emp... esse var é um objeto empresa,
basta na colunas colocar emp.nomeDaEmpresa
Como se fosseuma lista normal cara... o jsf vai reconhecer polo.empresaList como qual outra lista.
Vc não deve chamar no colum e sim definitna tabela
att Davi
Gostei + 0
29/03/2012
Jose Boas
Ex
Polo 1 Empresa 1
Polo 1 Empresa 2
Polo 3 Empresa 1
Veja como esta o meu <p:dataTable>
<p:dataTable
style=width:375px
paginator=true
rows=5
paginatorTemplate=
scrollable=false
value=#{poloBean.listaPoloEmpresa}
var=polo>
<f:facet name=header>
Lista de Empresas Associadas aos Polos
</f:facet>
<p:column style=width:10px sortBy=#{polo.codigoPolo}>
<f:facet name=header>Código</f:facet>
<h:outputText value=#{polo.codigoPolo}/>
</p:column>
<p:column style=width:40px sortBy=#{polo.nome}>
<f:facet name=header>Nome Polo</f:facet>
<h:outputText value=#{polo.nome}/>
</p:column>
<p:column style=width:40px sortBy=#{polo.empresaList}>
<f:facet name=header>Empresa</f:facet>
<h:outputText value=#{polo.empresaList}/>
</p:column>
<p:column style=width:4px>
<f:facet name=header>Exportar</f:facet>
<p:commandLink action=#{poloBean.desvinculaEmpresa} title=Exportar Polo update=:listaempresavinc>
<h:graphicImage library=imagens name=exportar16.png/>
<f:setPropertyActionListener value=# target=#{poloBean.empresaSelecionada}/>
</p:commandLink>
</p:column>
<f:facet name=footer>
Total de registros : #{fn:length(poloBean.listaPoloEmpresa)}
</f:facet>
</p:dataTable>
Gostei + 0
29/03/2012
Davi Costa
Um componente parecido como esses:
http://www.primefaces.org/showcase/ui/datatableExpandableRows.jsf
http://livedemo.exadel.com/richfaces-demo/richfaces/dataTable.jsf
Para a cada pólo agrupar suas empresas.
att Davi
Gostei + 0
29/03/2012
Jose Boas
idéia inicial era pegar polo em um combo e listar as empresas relacionadas em outro, eu ainda não fiz de listar o combo das empresas mas eu fiz um teste gravando apenas o polo para ver se dá certo mas ele retorna este erro.
Obs: eu consigo popular mas não consigo gravar
Erro de validação: o valor não é válido . Eu já fiz isso mas quando as tabelas são normais, no caso o polo é a tabela
que tem aquele esquema de ManyToMAny, e por coincidencia é nela que da problema, pois nos outros casos o meu conversor da certo.
Dá uma olhada em um conversor que funciona e a implementação no jsf e
Conversor
@FacesConverter(forClass=Categoria.class)
public class CategoriaConverter implements Converter {
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
if(value != null && value.trim().length() > 0 ){
Integer codigo = Integer.valueOf(value);
try{
CategoriaRN categoriaRN = new CategoriaRN();
return categoriaRN.carregar(codigo);
}catch(Exception e){
throw new ConverterException(Não foi possível encontrar a categoria de código + value + .+e.getMessage());
}
}
return null;
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
if (value != null){
Categoria categoria = (Categoria) value;
return categoria.getCodigo().toString();
}
return ;
}
}
JSF
<h:selectOneMenu id=categoria value=#{lancamentoBean.editado.categoria}>
<f:selectItems value=#{categoriaBean.categoriasSelect} />
</h:selectOneMenu>
Eu fiz seguinte o mesmo esquema veja o que da erro
Conversor
@FacesConverter(forClass=Polo.class)
public class PoloConverter implements Converter{
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
System.out.println(entrei no converter 1 = + value );
Polo polo = new Polo();
if(value != null && value.trim().length() > 0 ){
Integer codigo = Integer.valueOf(value);
try{
PoloRN poloRN = new PoloRN();
polo = poloRN.carregar(codigo);
return polo;
}catch(Exception e){
throw new ConverterException(Não foi possível encontrar o polo de código + value + .+e.getMessage());
}
}
return null;
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
System.out.println(entrei no converter 2 = + value );
if (value != null){
Polo polo = (Polo) value;
return polo.getCodigoPolo().toString();
}
return ;
}
}
JSF
<p:selectOneMenu id=polo value=#{planilhaBean.acidenteSelecionado.polo} style=width:180px>
<f:selectItems value=#{poloBean.poloSelect}/>
</p:selectOneMenu>
Gostei + 0
29/03/2012
Jose Boas
Vou fazer outros testes, depois se precisar eu retorno.
Gostei + 0
29/03/2012
Davi Costa
att Davi
Gostei + 0
29/03/2012
Jose Boas
Ex de como eu faço em uma situação normal
public List<SelectItem> getPoloSelect() {
if(this.poloSelect == null){
this.poloSelect = new ArrayList<SelectItem>();
PoloRN poloRN = new PoloRN();
List<Polo> polo = poloRN.listar();
SelectItem item = null;
for (Polo pol : polo){
item = new SelectItem(pol,pol.getNome());
item.setEscape(false);
this.poloSelect.add(item);
}
}
return this.poloSelect;
}
Como colocar a empresa SelectItem
Gostei + 0
30/03/2012
Davi Costa
vc vai pesquisar sobre ActionListener, pois ele espera um valor ser alterado para renderizar outro, tipo Estado e cidades
att Davi
Gostei + 0
30/03/2012
Jose Boas
att
José Luiz.
Gostei + 0
30/03/2012
Davi Costa
Pq estou pedindo que pesquise, pois vai depender da versão do jsf q vc utiliza, da biblioteca de componentes que vc está usa..(primefaces, icefaces, richfaces e por ai vai). Vc não está usando nenhuma, recomendo urgente o uso de alguma.
Espero ter ajudado
att Davi
Gostei + 0
30/03/2012
Jose Boas
Gostei + 0
30/03/2012
Jose Boas
public List<SelectItem> trocaEmpresaPolo(ValueChangeEvent event) {
System.out.println(Entrei no listener);
if (event.getNewValue() != event.getOldValue()) {
System.out.println(Vou chamar o polo select);
return getPoloEmpresaSelect();
}
return null;
}
public List<SelectItem> getPoloEmpresaSelect() {
System.out.println(Entrei para listar a empresa no combo);
SelectItem item = null;
System.out.println(Polo selecionado = + poloEditado.getNome());
if (this.poloEditado.getNome() != null) {
for (Empresa emp : this.poloEditado.getEmpresaList()){
System.out.println(Empresa listada = + emp.getNomeFantasia());
item = new SelectItem(emp,emp.getNomeFantasia());
item.setEscape(false);
this.poloEmpresaSelect.add(item);
}
}
return this.poloEmpresaSelect;
}
Meu jsf
Todos estes métodos estão no poloBean,mas onde eu gravo os dados que estão depois já inseridos é na planilhaBean.
Vou ter que fazer pelo poloBean, tudo ?
Gostei + 0
30/03/2012
Jose Boas
public List<SelectItem> trocaEmpresaPolo(ValueChangeEvent event) {
System.out.println(Entrei no listener);
if (event.getNewValue() != event.getOldValue()) {
System.out.println(Vou chamar o polo select);
return getPoloEmpresaSelect();
}
return null;
}
public List<SelectItem> getPoloEmpresaSelect() {
System.out.println(Entrei para listar a empresa no combo);
SelectItem item = null;
System.out.println(Polo selecionado = + poloEditado.getNome());
if (this.poloEditado.getNome() != null) {
for (Empresa emp : this.poloEditado.getEmpresaList()){
System.out.println(Empresa listada = + emp.getNomeFantasia());
item = new SelectItem(emp,emp.getNomeFantasia());
item.setEscape(false);
this.poloEmpresaSelect.add(item);
}
}
return this.poloEmpresaSelect;
}
Meu jsf
<p:selectOneMenu id=polo value=#{planilhaBean.acidenteSelecionado.polo} style=width:180px>
<f:selectItem itemLabel=Selecione o Polo itemValue=Nenhuma/>
<f:selectItems value=#{poloBean.poloSelect} var=polo itemValue=# itemLabel=#{polo.nome}/>
<p:ajax update=empresa Listener=#{poloBean.trocaEmpresaPolo} />
</p:selectOneMenu>
Todos estes métodos estão no poloBean,mas onde eu gravo os dados que estão depois já inseridos é na planilhaBean.
Vou ter que fazer pelo poloBean, tudo ?
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)