Consultar tabela @ManyToMany com JPQL

5 respostas
java
B

Pessoal, estou começando a utilizar o @ManyToMany. Tenho duas classes, Pessoa e Telefone, a tabela “Pessoas_Telefones” já foi criada e já está populada com os Ids de pessoa e telefone. Gostaria de exibir todos os dados de Pessoa e Telefone referente a cada ID através de uma consulta JPQL.

Código SQL ficaria assim:
SELECT * FROM pessoa p INNER JOIN pessoas_telefones pt ON p.id_pessoa=pt.pessoa_id
INNER JOIN telefone t ON t.id_telefone=pt.telefone_id;

Mas não estou conseguindo fazer essa pesquisa em JPQL devido a tabela “pessoas_telefone” e sobre o modo de formatação do INNER JOIN em JPQL.

Classe Pessoa:

@ManyToMany(cascade=CascadeType.ALL)

@JoinTable(name=Pessoas_Telefones,

joinColumns={@JoinColumn(name=PESSOA_ID)},

inverseJoinColumns={@JoinColumn(name=TELEFONE_ID)})

private List listaFones;

Classe Telefone:

@ManyToMany(mappedBy=“listaFones”)
private ListlistaPessoas;

Qual seria a solução?
Obrigado!

5 Respostas

S

Basta carregar uma lista de pessoas e a partir de uma instância de pessoa acessar o getListaFones() que será carregado.

Ex:

List<Pessoa> listPessoa = new ArrayList<>();// carregar a lista de pessoas
for(Pessoa pessoa: listPessoa) {
  System.out.println('Nome:'+pessoa.nome);
  System.out.println('Telefones:');
  
  // aqui o JPA/Hibernate entrará em ação executando a query para pegar os telefones
  // baseado na tabela Pessoas_Telefones
  for(Telefone telefone: pessoa.listaFones()) {
       System.out.println(telefone.getNumero());
  }
}
B

Meu interesse seria fazer em JPQL, pois estou fazendo uma aplicação Web.
Como ficaria em JPQL, sabe me informar?
Vlw.

V

Como foi falado, só de de executar:

select p from Pessoa p

você já consegue acessar através do getListaFones() mas, isso gerá a cada getListaFones() + 1 consulta. esse comportamento é chamado de LAZY

caso queira e tenha a certeza que sempre usará os dados do fone junto com a pessoa pode buscar dessa forma:

Select p from Pessoa p join fetch p.telefone.

a JPQL considera o nome da classe e o nome dos atributos. join fetch muda o comportamento para EAGER.

Aconselho a testar das duas formas e verificar no console as consultas geradas.

B

Select p from Pessoa p join fetch p.telefone.

Não entendi p.telefone, num seria p.listaFones? Como ficaria em JPQL para me retornar o resultado dos dados completos da pessoa e telefone através do id da Pessoa? Ex: A pessoa tem 3 telefones cadastrados.

Segue abaixo minha classe Pessoa e Telefone:

@Entity

@Table(name=Pessoa)

public class Pessoa{
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="id_pessoa")
private int id_pessoa;

@Column(name="nome")
private String nome;


@ManyToMany(cascade=CascadeType.ALL)
    @JoinTable(name="Pessoas_Telefones", 
     joinColumns={@JoinColumn(name="PESSOA_ID")},
     inverseJoinColumns={@JoinColumn(name="TELEFONE_ID")})
     private List<Telefone> listaFones;

@Entity

@Table(name=Telefone)

public class Telefone {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="id_telefone")
private int id_telefone;

@Column(name="numero")
private String numero;


@ManyToMany(mappedBy="listaFones")
private List<Pessoa>listaPessoas;
V

Isso bruno, não tinha reparado.

Mas na JPQL o que vale é sempre o nome da classe e dos atributos. esqueça as tabelas.

Select p from Pessoa p join fetch p.listaFones f where p.id = :id

Segue uns links interessantes para você estudar mais sobre JPA.

http://uaihebert.com/jpa-consultas-e-dicas/

http://uaihebert.com/jpa-mini-livro-primeiros-passos-e-conceitos-detalhados/

Criado 9 de abril de 2016
Ultima resposta 13 de abr. de 2016
Respostas 5
Participantes 3