Join com @Many-to-Many no JPA[RESOLVIDO]

9 respostas
R

Galera,

tenho a seguinte estrutura de BD:

tb_medico
id
nome

tb_hospital
id
nome

tb_medico_hospital
medico_id
hospital_id
qtdDias

Como fazer uma query no JPA que,dado o nome do hospital,liste todos os médicos desse hospital?Já dei uma googlada mas continuo perdido.Abs.

9 Respostas

visola

Onde estão suas entidades? Precisamos dela para te ajudar.
Mas talvez este tutorial te ajude: http://download.oracle.com/javaee/5/tutorial/doc/bnbtl.html

R
Medico
@Entity
@Table(name="tb_medico")
public class Medico {
	@Id
	@GeneratedValue
	Long id;
	String nome;
	@OneToMany
	List<MedicoHospital> medicoHospitais;
Hospital:
@Entity
@Table(name="tb_hospital")
public class Hospital {
	@Id
	@GeneratedValue
	Long id;
	String nome;
	
	@OneToMany
	List<MedicoHospital> medicoHospitais;
MedicoHospital:
@Entity
@Table(name="tb_medico_hospital")
public class MedicoHospital {
	@EmbeddedId
	MedicoHospitalPK pk = new MedicoHospitalPK();
	Integer dias;
PK
public class MedicoHospitalPK implements Serializable {
	@ManyToOne(fetch = FetchType.LAZY, optional = false)
	private Medico medico;
	
	@ManyToOne(fetch = FetchType.LAZY, optional = false)
	private Hospital hospital;
visola

Você precisa usar o JOIN.
Talvez isso funcione:

SELECT DISTINCT m FROM Medico m JOIN m.medicoHospitais h WHERE h.nome = :nome

Talvez o IN também funcione:

SELECT DISTINCT m FROM Medico m, IN (m.medicoHospitais) h WHERE h.nome = :nome
Lucas_Sorrentino

Você realmente precisa que seja em um query? Segundo o livro Java Persistence with Hibernate, vc poderia, em sua classe MedicoHospital, repetir os objetos que você pega no MedicoHospitalPk, assim tendo acesso direto a eles. Ficaria algo mais ou menos assim:

MedicoHospital:


    @Entity  
    @Table(name="tb_medico_hospital")  
    public class MedicoHospital {  
       
      @EmbeddedId  
        MedicoHospitalPK pk = new MedicoHospitalPK();  
  
       @ManyToOne(fetch = FetchType.LAZY, optional = false)  
        private Medico medico;  
         
        @ManyToOne(fetch = FetchType.LAZY, optional = false)  
        private Hospital hospital;  
        
        Integer dias;

PK

public class MedicoHospitalPK implements Serializable {  
       @ManyToOne(fetch = FetchType.LAZY, optional = false)  
        private Medico medico;  
         
        @ManyToOne(fetch = FetchType.LAZY, optional = false)  
        private Hospital hospital;
R

Lucas,tentei o q vc disse mas ocorreu isso:

Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: model.MedicoHospital column: hospital_id (should be mapped with insert="false" update="false")
Lucas_Sorrentino

Então, ele dá isso porque, como esses dois campos compõem o id da entidade, eles não podem ser modificados. Não é permitido alterar o id de entidades. Você pode fazer exatamente assim, como diz no console, que irá funcionar.

@Entity    
     @Table(name="tb_medico_hospital")    
     public class MedicoHospital {    
          
       @EmbeddedId    
         MedicoHospitalPK pk = new MedicoHospitalPK();    
     
        @ManyToOne(fetch = FetchType.LAZY, optional = false, insertable = false, updatable = false)    
         private Medico medico;    
            
         @ManyToOne(fetch = FetchType.LAZY, optional = false, insertable = false, updatable = false)    
         private Hospital hospital;    
           
         Integer dias;

Na minha aplicação, uso assim e funciona normalmente, apenas sem ser possível alterar o id. Eu só não uso esse “optional = false”.

R

Curioso,aqui tá dando esse erro:

The attribute insertable is undefined for the annotation type ManyToOne
Lucas_Sorrentino

Ah sim, me desculpa, esse atributo vai dentro do @JoinColumn. Erro meu. Nesse caso, você teria que implementar a anotação @JoinColumn.

R

Lucas,deu certo!

Muito obrigado.

Criado 21 de janeiro de 2011
Ultima resposta 21 de jan. de 2011
Respostas 9
Participantes 3