Problema em um join com consulta hql

23 respostas
W

Olá galera, tenho o objeto requisicao, em que tenho que fazer a consulta a partir dele, e tenho tbm o cotacao, que faz referencia a requisicao,

sse o objeto requisicao tivesse a a referencia eu faria assim:

hql.append("from Requisicao re");
hql.append("inner join fetch re.cotacao c");

mas não tem, em SQL normal eu faço assim e funciona:

SELECT * FROM REQUISICAO AS re
LEFT JOIN COTACAO AS c ON c.ID_REQUISICAO = re.id

como eu faço isso no hql???

23 Respostas

drsmachado

Explica direito que não entendi lhufas.

W

minha classe Requisicao:

Entity
@Table(name = "REQUISICAO")
public class Requisicao implements Identificavel<Long> {

	private static final long serialVersionUID = 1L;

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id;

	@Column(name = "NUM_SEQ")
	private Integer numSequencia;

	@Column(name = "ANO_SEQ")
	private Integer anoSequencia;

	@Label("lblRequisitante")
	@JoinColumn(name = "ID_REQUISICAO", nullable = true)
	@ManyToOne(fetch = FetchType.LAZY)
	private Usuario requisitante;

      //gets e sets

}

minha classe Cotacao:

@Entity
@Table(name = "COTACAO")
public class Cotacao implements Identificavel<Long> {

	private static final long serialVersionUID = 1L;

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "ID")
	private Long id;

	@Temporal(TemporalType.DATE)
	@Column(name = "DT_REQUISICAO")
	@Label("lblDataRequisicao")
	private Date dataFechamento;
	
	@Label("lblRequisicao")
	@JoinColumn(name = "ID_REQUISICAO", nullable = true)
	@ManyToOne(fetch = FetchType.LAZY)
	private Requisicao requisicao;

      //gets e sets

}

A minha consulta HQl parte de requisicao,
eu verifico se ela esta cotada ou nao

Eu faria assim, se Requisicao tivesse o atributo cotacao, mas e cotacao que contem requisicao

em sql normal, funciona:

SELECT * FROM REQUISICAO AS re  
LEFT JOIN COTACAO AS c ON c.ID_REQUISICAO = re.id

o que quero saber e como transformar esse sql normal em hql.

W

minha classe Requisicao:

Entity
@Table(name = "REQUISICAO")
public class Requisicao implements Identificavel<Long> {

	private static final long serialVersionUID = 1L;

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id;

	@Column(name = "NUM_SEQ")
	private Integer numSequencia;

	@Column(name = "ANO_SEQ")
	private Integer anoSequencia;

	@Label("lblRequisitante")
	@JoinColumn(name = "ID_REQUISICAO", nullable = true)
	@ManyToOne(fetch = FetchType.LAZY)
	private Usuario requisitante;

      //gets e sets

}

minha classe Cotacao:

@Entity
@Table(name = "COTACAO")
public class Cotacao implements Identificavel<Long> {

	private static final long serialVersionUID = 1L;

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "ID")
	private Long id;

	@Temporal(TemporalType.DATE)
	@Column(name = "DT_REQUISICAO")
	@Label("lblDataRequisicao")
	private Date dataFechamento;
	
	@Label("lblRequisicao")
	@JoinColumn(name = "ID_REQUISICAO", nullable = true)
	@ManyToOne(fetch = FetchType.LAZY)
	private Requisicao requisicao;

      //gets e sets

}

A minha consulta HQl parte de requisicao,
eu verifico se ela esta cotada ou nao

Eu faria assim, se Requisicao tivesse o atributo cotacao, mas e cotacao que contem requisicao

em sql normal, funciona:

SELECT * FROM REQUISICAO AS re  
LEFT JOIN COTACAO AS c ON c.ID_REQUISICAO = re.id

o que quero saber e como transformar esse sql normal em hql.

W

Entendeu agora brother

R

winigma:
Olá galera, tenho o objeto requisicao, em que tenho que fazer a consulta a partir dele, e tenho tbm o cotacao, que faz referencia a requisicao,

sse o objeto requisicao tivesse a a referencia eu faria assim:

hql.append("from Requisicao re");
hql.append("inner join fetch re.cotacao c");

mas não tem, em SQL normal eu faço assim e funciona:

SELECT * FROM REQUISICAO AS re
LEFT JOIN COTACAO AS c ON c.ID_REQUISICAO = re.id

como eu faço isso no hql???

No java voce ta colocando INNER, e no seu SQL na mao voce ta colocando LEFT, sao 2 coisas diferentes.

R

So responde 1 pergunta, o que voce quer trazer nesse sql ? voce quer trazer cotacao a partir de Requisicao ?

W

ta amigo, foi erro ali, era só pra demonstrar mas tanto faz se e left ou só join…

entendeu

W

Isso mesmo, quero buscar as cotações que contenha requisicao… no sql normal funciona, o que tem vem o que não tem aparece null…

Mas em hql, que deveria ser mais fácil a mesma técnica não funciona.

R

winigma:
ta amigo, foi erro ali, era só pra demonstrar mas tanto faz se e left ou só join…

entendeu

Entendi nao, mas esquece, e responda minha pergunta, voce quer trazer cotacao a partir de Requisicao ?

W

vc viu minha consulta em SQL??? quero que aquilo seja feito em hql, compreende? aquilo simplesmente funciona!!!

R

Tenta assim:

hql.append("SELECT re.cotacao FROM Requisicao re");
W

Isso não vai funcionar, pq minha entidade requisicao, não contém o atributo cotação, ele não faz referencia…

a entidade cotação que referencia requisicao, vc viu as entidades que postei?

R

Vi nao, pera la, hehehehe.

W
Cotação
@Entity  
@Table(name = "COTACAO")  
public class Cotacao implements Identificavel<Long> {  
  
    private static final long serialVersionUID = 1L;  
  
    @Id  
    @GeneratedValue(strategy = GenerationType.IDENTITY)  
    @Column(name = "ID")  
    private Long id;  
  
    @Temporal(TemporalType.DATE)  
    @Column(name = "DT_REQUISICAO")  
    @Label("lblDataRequisicao")  
    private Date dataFechamento;  
      
    @Label("lblRequisicao")  
    @JoinColumn(name = "ID_REQUISICAO", nullable = true)  
    @ManyToOne(fetch = FetchType.LAZY)  
    private Requisicao requisicao;  
  
      //gets e sets  
  
}
requisicao
Entity  
@Table(name = "REQUISICAO")  
public class Requisicao implements Identificavel<Long> {  
  
    private static final long serialVersionUID = 1L;  
  
    @Id  
    @GeneratedValue(strategy = GenerationType.IDENTITY)  
    private Long id;  
  
    @Column(name = "NUM_SEQ")  
    private Integer numSequencia;  
  
    @Column(name = "ANO_SEQ")  
    private Integer anoSequencia;  
  
    @Label("lblRequisitante")  
    @JoinColumn(name = "ID_REQUISICAO", nullable = true)  
    @ManyToOne(fetch = FetchType.LAZY)  
    private Usuario requisitante;  
  
      //gets e sets  
  
}
R

Na sua classe cotacao tem um referencia para Requisicao, porque nao faz ao contrario ?

hql.append("FROM Cotacao c where c.requisicao.id = :idRequisicao");
query.setParameter("idRequisicao", idRequisicao);
R

Ou, trazer todas as cotacoes que TENHAM requisicao, que é o que voce quer.

hql.append("FROM Cotacao c where c.requisicao.id is not null");

Voce pode usar outra coluna de requisicao, a que voce achar mais importante para filtrar os dados.

R

Serve ? Testou ae ?

W

Bom pq eu sempre terei requisicao, e as vezes cotacao,…

HQL nao tem todos os recursos de do SQL, se dar pra fazer em sql não é pra ser possível ser feito em hql?

W

nothing???

drsmachado

winigma:
Bom pq eu sempre terei requisicao, e as vezes cotacao,…

HQL nao tem todos os recursos de do SQL, se dar pra fazer em sql não é pra ser possível ser feito em hql?


HQL tem sim todos os recursos de SQL, porém, é preciso entender que SQL e HQL são diferentes entre si.
Eu creio que, no teu caso, você está pensando estruturado demais.
Creio que isso resolve

String hql = "Select c.requisicao FROM Cotacao c WHERE c.requisicao.id IS NOT NULL";

Como eu sei que deve ser isso?
Simples, eu criei uma associação entre os dois, para testar e fiz a seguinte consulta

String hql = "Select c.requisicao FROM Cotacao c WHERE c.requisicao.id <> 2";
		
		List<Requisicao> lista = session.createQuery(hql).list();
		
		for(Requisicao rs : lista){
			System.out.println(rs.getId() + " " + rs.getNumSequencia());
		}

Quando executei, tive os seguintes resultados

select requisicao1_.id as id0_, requisicao1_.ANO_SEQ as ANO2_0_, requisicao1_.NUM_SEQ as NUM3_0_ from COTACAO cotacao0_ inner join REQUISICAO requisicao1_ on cotacao0_.ID_REQUISICAO=requisicao1_.id where cotacao0_.ID_REQUISICAO<>2
1 123
3 123
4 123
5 123
6 123

Agora é com você, caro camaradinha.

W

Mas vc deixou as entidades do jeito que criei?

W

Se estiverem iguais a minha entidade, fiz o seguinte:

List<Requisicao> requisicoes = entityManager
				.createQuery(
						"Select c.requisicao FROM Cotacao c WHERE c.requisicao.id <> 2")
				.getResultList();
		// hql.append("left join  Cotacao c where c.requisicao = re ");

		return requisicoes;

E retorna nulo!!!

drsmachado

Iguais não tem como, não acha?
Aí vão as que eu criei.

@Entity
@Table(name = "COTACAO")
public class Cotacao implements Serializable {

	private static final long serialVersionUID = 1L;

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "ID")
	private Long id;

	@Temporal(TemporalType.DATE)
	@Column(name = "DT_REQUISICAO")
	private Date dataFechamento;

	@JoinColumn(name = "ID_REQUISICAO", nullable = true)
	@ManyToOne(fetch = FetchType.LAZY)
	private Requisicao requisicao;
//getters e setters
}
@Entity
@Table(name = "REQUISICAO")
public class Requisicao implements Serializable {
	private static final long serialVersionUID = 1L;

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id;

	@Column(name = "NUM_SEQ")
	private Integer numSequencia;

	@Column(name = "ANO_SEQ")
	private Integer anoSequencia;

	public Long getId() {
		return id;
	}
//getters e setters
}
Criado 1 de fevereiro de 2013
Ultima resposta 2 de fev. de 2013
Respostas 23
Participantes 3