[RESOLVIDO]Problema de Join com Hibernate

12 respostas
N

Olá a todos, estou querendo fazer um join entre duas tabelas que são duas classes na minha camada de modelo, encontrei varis duvidas parecdias com as minhas mas nenhuma das soluções que vi forma boas para mim, também olhei o site do hibernate e nada: http://docs.jboss.org/hibernate/core/3.6/reference/pt-BR/html/ e nada.

O que eu quero: fazer um join entre duas classes, hoje não faço mapeamento do Hibernate com o xml, tenho apenas o hibernate.properties que funciona com criterias mais simples.
@Entity
public class Funcionario{
        @Id
	@GeneratedValue
	private Long id;
	private String nome;
	private int numero;
        private Endereco endereco;

        @OneToMany
        @JoinColumn(name="numero") 
	public  Endereco SetEndereco() {  
		
		return endereco;  
		   
	} 

   /*outros get e set*/



}
public class Endereco{
        private int cidade;
        private int numero_funcionario; /*essa seria o campo que os une*/
	
       @ManyToOne
       @JoinColumn(name="numero_funcionario", insertable=false, updatable=false)
	public  Endereco getEndereco() {  
		  return  endereco;
	   
	} 

   /* outros get e set*/

}
Meu Util
public class HibernateUtil {
	private static SessionFactory factory;
	static {
	AnnotationConfiguration cfg = new AnnotationConfiguration();
	cfg.addAnnotatedClass(User.class);
	cfg.addAnnotatedClass(Funcionario.class);
	cfg.addAnnotatedClass(Endereco.class);

	factory = cfg.buildSessionFactory();
	}

	public Session getSession() {
	return factory.openSession();
	}

}
O meu DAO
public List<Funcionario> getTudo(int numero){
   
			
			Query q = session.createQuery(
					"from funcionario as f " +
					"left join endereco as e with  e.numero_funcionario.numero = :numero " +
					"where f.numero =  :numero"
			);
			
			List<Funcionario> resumo = q.list();
			return resumo;
				
		
	}
Ela da erro de
Path expected for join

Eu sei que esta tudo errado, alguem podia me dar uma direção? todas as soluções que eu vejo usam o xml para mapear as classes com a tabela, sendo que eu uso isso no util!! como faço?

Obrigada a todos :)

12 Respostas

D

Ola natasha eu uso assim o mapeamento entre classes:

@ManyToOne
    @JoinColumn(name = "codigo_sit_agenda")
    private Sit_Agenda codigo_sit_agenda;

public Sit_Agenda getCodigo_sit_agenda() {
        return codigo_sit_agenda;
    }

    public void setCodigo_sit_agenda(Sit_Agenda codigo_sit_agenda) {
        this.codigo_sit_agenda = codigo_sit_agenda;
    }
D

vc precisa dizer da onde essa coluna vem, por isso da esse erro, faça mais ou menos como eu te passei :wink:

N
Oi natasha o erro que deu aí , é que quando se faz um join com hql vc precisa colocar o caminho que o relacionamento faz no caso ao invéz de:
4.             Query q = session.createQuery(  
   5.                     "from funcionario as f " +  
   6.                     "left join endereco as e with  e.numero_funcionario.numero = :numero " +  
   7.                     "where f.numero =  :numero"  
   8.             );  
             
  13.           
  14.     }
seria
4    Query q = session.createQuery(  
   5.                     "from funcionario as f " +  
   6.                     "left join f.endereco as e with  e.numero_funcionario.numero = :numero " +  
   7.                     "where f.numero =  :numero"  
   8.             );  
     
  13.           
  14.     }
N

Olá DeGuedes, obrigada pela resposta. :slight_smile:

Eu fiz o que vc mandou, sendo que o erro continua, esse erro não seria por conta do meu DAO?

public List<Funcionario> getTudo(int numero){  
     
              
            Query q = session.createQuery(  
                    "from funcionario as f " +  
                    "left join endereco as e with  e.numero_funcionario.numero = :numero " +  
                    "where f.numero =  :numero"  
            );  
              
            List<Funcionario> resumo = q.list();  
            return resumo;  
                  
          
    }
D

eu uso HQL, nao tenho certeza, mas pode ser… faça como o neno falou! :wink:

N
Obrigada neno, fiz essas alterações, mas continua o erro, essa é a minha classe que eu uso para testar, ela esta com erro?
public static void main(String [] args){
		
		Session session = (Session) new HibernateUtil().getSession();
		FuncionarioDAO funcionarioDao = new FuncionarioDAO(session);
		
		System.out.println("*****Listando Tudo*******");
	
		int numero = 12;
		for (Funcionario t :  funcionarioDao.getTudo(numero)) {
	
		System.out.println(t.getNome());
                System.out.println(t.getCidade());
	
		
		}

	
	}
N

Natasha acho que tem algumas alterações que vc precisa fazer.., seu relacionamento de funcionario é funcionario 1 - enderecos n ? tipo um funcionario tem muitos enderecos?

se for no caso, sua classe Funcionario ficaria..

# @Entity  
# public class Funcionario{  
#         @Id  
#     @GeneratedValue  
#     private Long id;  
#     private String nome;  
#     private int numero;  
#         @OneToMany  
#         @JoinColumn(name="numero")   // ou vc coloca o mapeamento no atributo ou no get, no set acho que nao rola
#         private List<Endereco> endereco;  
#   

#     public  Endereco SetEndereco() {    
#           
#         return endereco;    
#              
#     }   
#   
#    /*outros get e set*/

sua classe endereco

1. public class Endereco{  
   2.         private int cidade;  
   3.         private Funcionario funcionario; /*essa seria o campo que os une (é aconcelhavel usar uma referencia da propria classe, ao inves de um atributo primitivo)*/  
   4.       
   5.        @ManyToOne  
   6.        @JoinColumn(name="numero_funcionario", insertable=false, updatable=false)  
   7.     public  Funcionario getFuncionario() {    
   8.           return  funciorario;  
   9.          
  10.     }   
  11.   
  12.    /* outros get e set*/  
  13.   
  14. }
e o seu dao
1. public List<Funcionario> getTudo(int numero){  
   2.      
   3.               
   4.             Query q = session.createQuery(  
   5.                     "from Funcionario as f " +  
   6.                     "left fetch join f.endereco as e where f.numero =  :numero"  
   8.             );  // usando f.endereco ele ja faz o join automatico assim tras os funcionarios com os enderecos
   9.               
  10.             List<Funcionario> resumo = q.list();  
  11.             return resumo;  
  12.                   
  13.           
  14.     }
e no seu main
# public static void main(String [] args){  
#           
#         Session session = (Session) new HibernateUtil().getSession();  
#         FuncionarioDAO funcionarioDao = new FuncionarioDAO(session);  
#           
#         System.out.println("*****Listando Tudo*******");  
#       
#         int numero = 12;  
#         for (Funcionario t :  funcionarioDao.getTudo(numero)) {  
#       
#         System.out.println(t.getNome());  
#                 System.out.println(t.getEndereco().getCidade());  //alteracao aqui
#       
#           
#         }  
#   
#       
#     }  
#

assim é só algumumas dicas...
voce pode dar uma olhada em alguma coisa na net sobre mapeamento jpa e hql pra aprofundar mais,
mas faz isso aí , e ve o que acontece, e se der pau posta o print stack trace do console aí...

N

ah e o a string query do hql é case sensitive, ela usa a propria classe, entao se for fazer algo tipo "from Funcionario as f ", o F (Funcionario) tem q ser em caixa alta, igual o da classe :slight_smile:

N

Olá neno, muito obrigada pela sua resposta :)

eu fiz o que vc mandou, só que não entendi uma coisa:
na classe Funcionario vc só colocou apenas o SetEndereco(), mas na classe que eu uso para testar vc esta chamando um getEndereco(), não entendi esse get.

Na classe que eu uso para testar coloquei o SetFuncionario que é o que existe e deu o seguinte erro:

nexpected token: fetch near line 1, column 65 [select cidade as cidade from modelo.Funcionario as f left fetch join f.endereco as e  ]
for (Funcionario t : funcionarioDao.getTudo(numero)) {
		
		System.out.println(t.SetFuncionario().getCidade());
		
}
Esse é o meu DAO
1. public List<Funcionario> getTudo(int numero){    
2.        
3.                 
4.           Query q = session.createQuery("select cidade as cidade "+
					"from Funcionario as f " +
					"left fetch join f.endereco as e  " 
					); // usando f.endereco ele ja faz o join automatico assim tras os funcionarios com os enderecos  
9.                 
10.             List<Funcionario> resumo = q.list();    
11.             return resumo;    
12.                     
13.             
14.     }

Obrigada pela ajuda

N

OI natasha,
o getEndereco que eu fiz tava errado mesmo rs..

na verdade eu quis simplificar, no caso na sua classe Funcionario vc teria um get e um set normal mesmo.pro atributo endereco, que a IDE gera automatico
@OneToMany    
         @JoinColumn(name="numero")   // ou vc coloca o mapeamento no atributo ou no get, no set acho que nao rola  
         private List<Endereco> endereco;    
     
 
     public List< Endereco> getEndereco() {      
             
         return endereco;      
                
     }   

public void setEndereco(List< Endereco> endereco){
   this.endereco = endereco
}

o no seu dao foi outra falha minha hehe

# 1. public List<Funcionario> getTudo(int numero){    
# 2.        
# 3.                 
#         Query q = session.createQuery("select f from Funcionario f left  join fetch f.endereco  e  "   
#                     ); // eu coloquei a palavra fetch no lugar errado 
# 9.                 
# 10.             List<Funcionario> resumo = q.list();    // no caso nao seria select cidade e sim f de funcionario, porque o metodo retorna uma lista de funcionario e nao de cidade
# 11.             return resumo;    
# 12.                     
# 13.             
# 14.     }
e como vc na consulta voce retornara uma lista de funcionarios ja com os enderecos de cada funcionario populados, vc vai percorrer um for dentro do outro
public static void main(String [] args){    
             
        Session session = (Session) new HibernateUtil().getSession();    
        FuncionarioDAO funcionarioDao = new FuncionarioDAO(session);    
            
        System.out.println("*****Listando Tudo*******");    
        
        int numero = 12;    
        for (Funcionario t :  funcionarioDao.getTudo(numero)) {    
       
         System.out.println(t.getNome());    

               for(Endereco e : f.getEndereco){
                 System.out.println(" cidade " + e.getCidade());  //alteracao aqui  
        }
             
         }    
     
         
     }

pacho que consertei agora, desulpa a bagunça que fiz hehe

N

Obrigada neno. :slight_smile:

Fiz o que você mandou, ele aparece a query no console, mas dá daus msg de erro:

could not execute query

Unknown column 'endereco1_.funcionario' in 'field list'
N

Olá, consegui resolver, não sei se fiz bem, ele estava fazer o join com o ID do funcionario, mas na verdade eu queria que fosse com o numero do funcionario, tornei o
@Id no numero, que acaba se repetindo mais de uma vez, mas como ele não deu problema, vou dar prosseguimento.

Obrigada a todos pela ajuda.

:slight_smile:

Criado 9 de novembro de 2010
Ultima resposta 11 de nov. de 2010
Respostas 12
Participantes 3