Ajuda com HQL e consulta usando FKs [RESOLVIDO]

Olá, estou precisando fazer uma consulta, usando HQL, em uma tabela que possui FKs mas não sei bem como.

O caso é que tenho uma tabela chamada Transacao e uma Estabelecimento. A primeira possui atributos normais e uma FK que faz referência ao campo id da tabela Estabelecimento.

Preciso executar uma consulta que exiba alguns campos da tabela Transacao mas também preciso exibir o campo “nome” da tabela Estabelecimento e pra isso preciso utilizar a FK da tabela Transacao.

tentei usar:

    SELECT ts.id, ts.numeroPedido, ts.valor, ts.dataPedido, et.nome FROM Transacao ts, Estabelecimento et WHERE ts.estabelecimento = et.id  

mas apareceu:
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to models.Transacao

Se alguém puder me dar uma dica eu ficaria muito grato!

Olá BrenoBex,

Como q vc fez o mapeamento dessa classe?

e aqi no final:

WHERE ts.estabelecimento = et.id

Nao seria:

WHERE ts.estabelecimento = :id").setParameter(“id”, numeroDoId);

Amigo quando se trabalha com Persistencia não precisa realizar esse tipo de select, com o HQL você faria um select em transação passando o ID referente a transação escolhida e depois quando o objeto ou List que recebe o retorno da consulta estiver populado simplesmente pegaria o o estabelecimento usando

Esta é a Query:

@NamedQueries({
       @NamedQuery(name = "ListarPorTransacaoID", query = "from Transacao t where t.id = :id ")
})
Transacao objTransacao; // objTransacacao ja populado com o retorno do select
objTransacao.getEstabelecimento(); // estabelecimento é um atributo da Classe Transacao, que na base representa uma FK
objTransacao.getEstabelecimento().getNome(); // nome é um atributo da classe estabelecimento que por sua vez é um atributo da classe Transação!!!

lembre-se o Hibernate é ninja, ele faiz a maioria das coisas pra vc!!! espero ter ajudado, abraços!

Rafael e Rafael obrigado por responderem,
minhas classes estão assim:

Classe transacao:

[code]@Entity
public class Transacao {

@Id
@GeneratedValue
private int id;

@Column()
private String numeroPedido; 
@Column()
private String valor;
@Column()
private String dataPedido;
@Column() 
private int estabelecimento;

//getters e setters
[/code]

Estabelecimento:

[code]@Entity
public class Estabelecimento {
@Id
@GeneratedValue
private int id;

@Column()
private String nome;

//getters e setters
[/code]

TransacaoDao (que faz a consulta no banco)

public List <Transacao> consultarAll() throws Exception{
		Session session;
		session = HibernateUtil.getInstanceTS();
		Transaction tx = null;
		tx = session.beginTransaction();	
		
		List <Transacao> ts;	
		Query q = session.createQuery("FROM Transacao as ts ORDER BY ts.id DESC");
		q.setMaxResults(50);
		ts = q.list();
		return ts;
	}

E por fim a página JSP (monitTransacao), onde através de um while eu vou exibindo o que eu quero (através do display tag lib)

<%
	List<Transacao> tsList = new ArrayList<Transacao>();
	TransacaoDao daoTS = new TransacaoDao();
	tsList = daoTS.consultarAll(); 
	Transacao achei = null;
			
	try{
	    List<Transacao> listaAchei = new ArrayList<Transacao>(); 
  		ListIterator iter = tsList.listIterator();
  			
		while(iter.hasNext()){
			achei = (Transacao) iter.next();
			listaAchei.add(achei);
		}
		request.setAttribute( "achei", listaAchei ); //aki é onde manda a lista  
			
%>  
<center>
<display:table name="achei" id="tabela">
  	<display:column property="numeroPedido" title="Número do Pedido" style="width:30%; text-align: center"/>
  	<display:column property="valor" title="Valor" style="width:40%;"/> 
  	<display:column property="dataPedido" title="Data do Pedido" style="width:70%;"/>
</display:table>

<%		
	}catch(Exception e){
		out.print("ERRO");
		e.printStackTrace();
	}
%>

Reparem que se eu pedir pra exibir apenas os atributos “normais” da classe transacao, vai sem problemas, mas se eu pedir pra mostrar o estabelecimento ocorre aquele erro.
No caso eu teria que modificar o jeito que eu faço o while e guardo os resultados da busca?

Coloque assim na entidade

[code]@Entity
public class Transacao {

@Id  
@GeneratedValue  
private int id;  
  
@Column()  
private String numeroPedido;   
@Column()  
private String valor;  
@Column()  
private String dataPedido;  
@OneToOne // ou @ManyToOne depende do que vc quer
private Estabelecimento  estabelecimento;  

//getters e setters [/code]

e para resgatar os valores, use o Criteria, eu acho melhor (mas é so opinião)

Obrigado Rafael,
talvez eu dê uma estudada no Criteria e tento fazer com ele, porque não to conseguindo com HQL.

Vou tantar mais um pouco com HQL mas se nao conseguir eu tento com Criteria

Obrigado aos dois que me ajudaram!!

exatamente como o meu chara disse acima você necessita de um atributo de Estabelecimento dentro de transação, assim dado uma transação você tambem tera o estabelecimento relacionado a ela, do jeito que você estava fazendo não tinha relacionamento entre as tabelas “Transação” e “Estabelecimento” agora do jeito que o Rafa postou acima na tabela Transacao no vc tera um id referente ao estabelecimento, assim sendo quando vc obter a Transação o estabelecimento vira junto para isso basta usar o exemplo que mostrei acima, ou o Criteria, obs: não indiquei o Criteria pois não o conheco ainda, preciso estuda-lo!!! abraços!!!

Mas vc viu a entidade como ficou?

O hibernate vai mapear o ID no banco, mas quando vc consultar uma Transacao, ele vai consultar junto o Estabelecimento.

na verdade ele vai consultar o estabelecimento só quando vc precisar dele, ou seja, quando vc der um

Transacao ts = dao.consultar(1); ts.getEstabelecimento();

mas fique atento pois se você pegar um estabelecimento depois de fechar a session, ele não vai conseguir trazer para você, então, nesses casos nós devemos usar o

Antes de fechar a session do hibernate.

é isso ai!

Rafael e Rafael eu consegui !!!

e nao cheguei a precisar utilizar Criteria!! usei as dicas de ambos e fiz algumas pequenas modificaçõe na classe Transação e na pagina JSP.

Transacao:
Troquei o int estabelecimento por Estabelecimento e tmb tive que acrescentar o annotation JoinColumn

@OneToOne
@JoinColumn (name = "estabelecimento", referencedColumnName = "id", updatable = true, insertable = true)
private Estabelecimento estabelecimento = new Estabelecimento();

monitTransacao.jsp:
usei a dica de estabelecimento.getNome() pra exibir os dados

<display:column title="Estabelecimento" style="width:70%;">
      ${tabela.estabelecimento.getNome()}  
 </display:column>

funcionou certinho!!!
Realmente o Hibernate é ninja, ele faz quase tudo pra gente kkkkk

Mais uma vez agradeço aos dois pelas dicas e vontade de ajudar!!!
Vlw mesmo!!! :smiley: