Problemas com JOIN - Anotações Hibernate

6 respostas
L

Boa tarde galera.

Sou iniciante no desenvolvimento Web com Struts e Hibernate e por esse motivo estou com um problema. Estou usando Postgres.

Tenho duas tabelas: Tela e Acao. O relacionamento entre elas é de um para muitos respectivamente. Ou seja, uma tela pode ter várias ações.

Meu Bean Acao esta assim:

@Entity
@Table(name = "acao", schema = "public")
public class Acao implements java.io.Serializable {

	@Id
	@Column(name = "cod_acao", unique = true, nullable = false)
	private codAcao;

	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "cod_tela")
	private Tela tela;

	........

}

Meu Bean Tela esta assim:

@Entity
@Table(name = "tela", schema = "public")
public class Tela implements java.io.Serializable {


	@Id
	@Column(name = "cod_tela", unique = true, nullable = false)
	private int codTela;

	@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "tela")
	private Set<Acao> acaos = new HashSet<Acao>(0);


	........


}

Meu HQL está assim:

Ele me retorna o valor vazio. Já tentei com LEFT JOIN e também retornou vazio. Lembrando que existe uma tela registrada no banco, porém, não existe nenhuma ação vinculada a essa tela.

Alguém sabe o que pode estar acontecendo?

6 Respostas

L

UP

von.juliano

Se você está usando HQL, não há necessidade de usar join. E como você está usando FetchType.LAZY, você pode fazer o seguinte:

List list = bd.createQuery("from Tela").list();E depois, para obter as ações associadas:

list.get(0).getAcaos();

Vê se te ajuda! Flw! :thumbup:

L

Cara, vlw, consegui resolver esse problema. Porém, agora tenho outro…

Eu tenho os seguintes Beans

package erpvictory.beans.comum;

/**
 * Tela generated by hbm2java
 */
@Entity
@Table(name = "tela", schema = "public")
public class Tela implements java.io.Serializable {

	private int codTela;
	private Sistema sistema;
	private Tela tela;
	//private int codSistema;
	private String nome;
	private Boolean ativo;
	private Boolean manutencao;
	private Integer ordem;
	private Arquivo arquivo;
	
	private List<Tela> telas = new ArrayList<Tela>();
	private List<Acao> acaos = new ArrayList<Acao>();

	public Tela() {
	}

	public Tela(int codTela) {
		this.codTela = codTela;
	}

	public Tela(int codTela, Sistema sistema, Tela tela, String nome,
			Boolean ativo, Boolean manutencao, Integer ordem, List<Tela> telas,
			List<Acao> acaos) {
		this.codTela = codTela;
		this.sistema = sistema;
		this.tela = tela;
		this.nome = nome;
		this.ativo = ativo;
		this.manutencao = manutencao;
		this.ordem = ordem;
		this.telas = telas;
		this.acaos = acaos;
	}

	@Id
	@Column(name = "cod_tela", unique = true, nullable = false)
	public int getCodTela() {
		return this.codTela;
	}

	public void setCodTela(int codTela) {
		this.codTela = codTela;
	}

	@ManyToOne(fetch = FetchType.EAGER)
	@JoinColumn(name = "cod_sistema")
	public Sistema getSistema() {
		return this.sistema;
	}

	public void setSistema(Sistema sistema) {
		this.sistema = sistema;
	}
	
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "cod_arquivo")
	public Arquivo getArquivo() {
		return this.arquivo;
	}

	public void setArquivo(Arquivo arquivo) {
		this.arquivo = arquivo;
	}
	

	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "cod_tela_pai")
	public Tela getTela() {
		return this.tela;
	}

	public void setTela(Tela tela) {
		this.tela = tela;
	}

	@Column(name = "nome")
	public String getNome() {
		return this.nome;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}

	@Column(name = "ativo")
	public Boolean getAtivo() {
		return this.ativo;
	}

	public void setAtivo(Boolean ativo) {
		this.ativo = ativo;
	}

	@Column(name = "manutencao")
	public Boolean getManutencao() {
		return this.manutencao;
	}

	public void setManutencao(Boolean manutencao) {
		this.manutencao = manutencao;
	}

	@Column(name = "ordem")
	public Integer getOrdem() {
		return this.ordem;
	}

	public void setOrdem(Integer ordem) {
		this.ordem = ordem;
	}

	@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "tela")
	public List<Tela> getTelas() {
		return this.telas;
	}

	public void setTelas(List<Tela> telas) {
		this.telas = telas;
	}

	@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "tela")
	public List<Acao> getAcaos() {
		return this.acaos;
	}

	public void setAcaos(List<Acao> acaos) {
		this.acaos = acaos;
	}

	/*@Column(name = "cod_sistema", insertable=false, updatable=false)
	public int getcodSistema() {
		return this.codSistema;
	}

	public void setcodSistema(int cod_sistema) {
		this.codSistema = cod_sistema;
	}*/
	
	
	

}
package erpvictory.beans.comum;

import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@SuppressWarnings("serial")
@Entity
@Table(name = "acao", schema = "public")
public class Acao implements java.io.Serializable {

	private int codAcao;
	private AcaoTipo acaoTipo;
	private Tela tela;
	private String nome;
	private String acao;
	private String javascript;
	private Boolean padrao;
	private Boolean ativo;
	private Set<Usuario> usuarios = new HashSet<Usuario>(0);
	private Set<Perfil> perfils = new HashSet<Perfil>(0);

	public Acao() {
	}

	public Acao(int codAcao) {
		this.codAcao = codAcao;
	}

	public Acao(int codAcao, AcaoTipo acaoTipo, Tela tela, String nome,
			String acao, String javascript, Boolean padrao, Boolean ativo,
			Set<Usuario> usuarios, Set<Perfil> perfils) {
		this.codAcao = codAcao;
		this.acaoTipo = acaoTipo;
		this.tela = tela;
		this.nome = nome;
		this.acao = acao;
		this.javascript = javascript;
		this.padrao = padrao;
		this.ativo = ativo;
		this.usuarios = usuarios;
		this.perfils = perfils;
	}

	@Id
	@Column(name = "cod_acao", unique = true, nullable = false)
	public int getCodAcao() {
		return this.codAcao;
	}

	public void setCodAcao(int codAcao) {
		this.codAcao = codAcao;
	}

	@ManyToOne(fetch = FetchType.EAGER)
	@JoinColumn(name = "cod_tipo_acao")
	public AcaoTipo getAcaoTipo() {
		return this.acaoTipo;
	}

	public void setAcaoTipo(AcaoTipo acaoTipo) {
		this.acaoTipo = acaoTipo;
	}

	@ManyToOne(fetch = FetchType.EAGER)
	@JoinColumn(name = "cod_tela", updatable = false, insertable = false)
	public Tela getTela() {
		return this.tela;
	}

	public void setTela(Tela tela) {
		this.tela = tela;
	}

	@Column(name = "nome")
	public String getNome() {
		return this.nome;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}

	@Column(name = "acao", length = 150)
	public String getAcao() {
		return this.acao;
	}

	public void setAcao(String acao) {
		this.acao = acao;
	}

	@Column(name = "javascript")
	public String getJavascript() {
		return this.javascript;
	}

	public void setJavascript(String javascript) {
		this.javascript = javascript;
	}

	@Column(name = "padrao")
	public Boolean getPadrao() {
		return this.padrao;
	}

	public void setPadrao(Boolean padrao) {
		this.padrao = padrao;
	}

	@Column(name = "ativo")
	public Boolean getAtivo() {
		return this.ativo;
	}

	public void setAtivo(Boolean ativo) {
		this.ativo = ativo;
	}

	@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "acaos")
	public Set<Usuario> getUsuarios() {
		return this.usuarios;
	}

	public void setUsuarios(Set<Usuario> usuarios) {
		this.usuarios = usuarios;
	}

	@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "acaos")
	public Set<Perfil> getPerfils() {
		return this.perfils;
	}

	public void setPerfils(Set<Perfil> perfils) {
		this.perfils = perfils;
	}

}

As tabelas são essas:

CREATE TABLE acao
(
  cod_acao serial NOT NULL,
  cod_tela integer,
  cod_tipo_acao character(1),
  nome character varying(255),
  acao character varying(150),
  javascript character varying(255),
  padrao boolean,
  ativo boolean,
  CONSTRAINT pk_acao PRIMARY KEY (cod_acao),
  CONSTRAINT fk_acao__acao_tipo FOREIGN KEY (cod_tipo_acao)
      REFERENCES acao_tipo (cod_acao_tipo) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE RESTRICT,
  CONSTRAINT fk_acao__tela FOREIGN KEY (cod_tela)
      REFERENCES tela (cod_tela) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
)

CREATE TABLE tela ( cod_tela serial NOT NULL, cod_sistema integer, cod_tela_pai integer, nome character varying(255), ativo boolean, manutencao boolean, ordem integer, tipo character(1) NOT NULL, cod_arquivo integer, CONSTRAINT pk_tela PRIMARY KEY (cod_tela), CONSTRAINT fk_tela__arquivo FOREIGN KEY (cod_arquivo) REFERENCES arquivo (cod_arquivo) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE SET NULL, CONSTRAINT fk_tela__sistema FOREIGN KEY (cod_sistema) REFERENCES sistema (cod_sistema) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE RESTRICT, CONSTRAINT fk_tela__tela FOREIGN KEY (cod_tela_pai) REFERENCES tela (cod_tela) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE RESTRICT )

Eu preciso fazer um select assim com HQL:
SELECT
t.*,
a.nome as acao_padrao
FROM tela t
LEFT JOIN acao a ON t.cod_tela=a.cod_tela AND a.padrao=true

A HQL ficou assim:
SELECT t, a.nome FROM Tela t LEFT OUTER JOIN t.acaos a WITH a.padrao=true

Peguei o SQL que ele gera e monta direitinho o resultado, só que monta o Bean de um jeito que eu não consigo listar os dados. Estou meio perdido com relação a isso.

Alguem pode me ajudar?

L

Leandro,

leandro.francoso:

Eu preciso fazer um select assim com HQL:
SELECT
t.*,
a.nome as acao_padrao
FROM tela t
LEFT JOIN acao a ON t.cod_tela=a.cod_tela AND a.padrao=true

A HQL ficou assim:
SELECT t, a.nome FROM Tela t LEFT OUTER JOIN t.acaos a WITH a.padrao=true

Peguei o SQL que ele gera e monta direitinho o resultado, só que monta o Bean de um jeito que eu não consigo listar os dados. Estou meio perdido com relação a isso.

Alguem pode me ajudar?

Se você fizer um select select t from Tela t o retorno é uma coleção de objetos do tipo Tela. Porém, se você fizer um select select t.nome, t.descricao from Tela t o retorno será uma coleção de arrays com duas colunas (de nome ou descrição). Ou você retorna o t inteiro, com os valores preenchidos, ou você pode utilizar esse recurso do Hibernate http://www.hibernate.org/hib_docs/v3/reference/en-US/html/queryhql-select.html:

select new Family(mother, mate, offspr) from DomesticCat as mother join mother.mate as mate left join mother.kittens as offspr

[]s
Liss.

L

Legal, consegui trazer o que eu queria mas agora estou com outra dúvida. :roll:

Estou fazendo o seguinte select:

FROM Tela t LEFT JOIN t.acaos a WITH a.padrao=true WHERE t.tela.codTela=null

Ele me traz um list de objetos Tela e Acao. O problema é que eu não sei listar esse resultado com Struts ou na própria Action para retornar um HashMap.

Estou mandando essa dúvida pois não acho em lugar nenhum esse problema na Internet.

arthurminarini

coloca um select antes

select tela FROM Tela t LEFT JOIN t.acaos a WITH a.padrao=true WHERE t.tela.codTela=null

ai traz só as telas se vc deixar assim cria então um interator e um array objeto do tipo object
e pega eles pelos indices o 0 é tela e o 1 é a ação ai vc popula manualmente os objetos.

Criado 2 de fevereiro de 2009
Ultima resposta 6 de fev. de 2009
Respostas 6
Participantes 4