Início > Programação > Como Fazer um Join Utilizando a API de Criteria

Como Fazer um Join Utilizando a API de Criteria

É comum precisar fazer um ou mais joins em uma consulta para obter um determinado resultado. A API de Criteria é uma boa alternativa para fazer uma consulta complexa, type-safe e com parâmetros dinâmicos como expliquei em outro artigo.

O Join permite que você navegue de uma entidade à outra através de seus atributos em relacionamentos OneToMany e ManyToOne. Para esse exemplo, assumo que você está familiarizado com a API de persistência do Java. Considere o relacionamento abaixo:

pessoa

Figura 1 – Relacionamento entre Pessoa e Pet

A implementação simplificada abaixo desdobra esse relacionamento:

@Entity
@Table(name = "TBL_PET")
public class Pet {
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   @Column(name = "PK_PET")
   private Long id;
}

@Entity
@Table(name = "TBL_PESSOA")
public class Pessoa {
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   @Column(name = "PK_PESSOA")
   private Long id;
   
   @Fetch(FetchMode.SUBSELECT)
   @OneToMany(fetch = FetchType.EAGER, cascade = { CascadeType.REMOVE })
   @JoinTable(name = "TBL_PESSOA_PET", 
     joinColumns = {
       @JoinColumn(name = "FK_PESSOA", referencedColumnName = "PK_PESSOA")
       }, 
     inverseJoinColumns = {
       @JoinColumn(name = "FK_PET", referencedColumnName = "PK_PET")
       }
   )
   private List<Pet> pets = new ArrayList<Pet>();
}

Vamos criar um método que, dada uma lista de identificadores de Pet, retorna todas as Pessoas que os contém:

public List<Pessoa> findPessoas(List<Long> idsPets){
   CriteriaBuilder criteriaBuilder = 
      entityManager.getCriteriaBuilder();
   CriteriaQuery<Pessoa> criteriaQuery =    
       criteriaBuilder.createQuery(Pessoa.class);
   Root<Pessoa> root = criteriaQuery.from(Pessoa.class);
   List<Predicate> predicateList = new ArrayList<Predicate>();

   Join<Pessoa, Pet> join = root.join("pets");
   Path<Long> campoPetId = join.get("id");
   Predicate predPets = criteriaBuilder.isTrue(campoPetId.in(idsPets));
   predicateList.add(predPets);

   Predicate[] predicates = new Predicate[predicateList.size()];
   predicateList.toArray(predicates);
   criteriaQuery.where(predicates);

   TypedQuery<Pessoa> jpaQuery = entityManager.createQuery(criteriaQuery);
   List<Parceiro> resultList = jpaQuery.getResultList();
   return resultList;
}

Referências

1. [http://stackoverflow.com/questions/9445426/jpa-criteriaquery-onetomany]
2. [http://stackoverflow.com/questions/9281106/jpa-criteria-api-predicates-for-objects-in-onetomany-relationship]
3. [http://stackoverflow.com/questions/9025196/how-to-use-jpa-criteria-api-when-joining-many-tables]
4. [https://docs.jboss.org/hibernate/entitymanager/3.5/reference/en/html/querycriteria.html]

Anúncios
  1. Nenhum comentário ainda.
  1. No trackbacks yet.

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

%d blogueiros gostam disto: