简体   繁体   中英

JPA Criteria - where clause

I have a Entity class which contain some primitive data type and contain some collection of object which have OneToMany relation and ManyToOne relation.

And when I am Fetching data by using JPA Criteria then I am getting all the data but I want to filter the result by using JPA Criteria where clause , I can apply in its primitive data type and its work fine , I have to apply where clause in collection of object which have OneToMany relation some have ManyToOne relation but how to apply where clause in these case , can you tell me ?

I did that on this way:

Repository

@Query(value = "SELECT e FROM Employee e JOIN e.user u JOIN u.role r JOIN r.grants g where g = :grant")
List<Employee> findByGrant(@Param("grant") Grant grant);

Grant is related ManyToMany with Role wich is related OneToOne with employee.

So you just need to Join the Object and filter with an object setting the PKEY (ID).

Entities

@Entity
public class Employee {

  @OneToOne
  @JoinColumn(name = "user_id")
  private User user;
}

@Entity
public class User implements UserDetails {

  /**
   * 
   */
  private static final long serialVersionUID = 7854391295707311278L;

 @Id
 @GeneratedValue(strategy = GenerationType.AUTO)
 private Long id;

 @OneToOne
 @JoinColumn(name = "role_id")
 private Role role;

}

@Entity
public class Role {

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private Long id;

  @ManyToMany(fetch=FetchType.EAGER, cascade=CascadeType.MERGE)
  @JoinTable(
    name = "role_has_grant", 
    joinColumns = {
      @JoinColumn(name = "role_id", referencedColumnName = "id") 
    },
     inverseJoinColumns = {
      @JoinColumn(name = "grant_id", referencedColumnName = "id") 
     })
   @Fetch(FetchMode.SELECT)
   private List<Grant> grants;
}

@Entity
public class Grant implements GrantedAuthority {
  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private Long id;
}

Another relation

@Query(value = "SELECT a FROM Activity a JOIN a.task t WHERE t.project = :project AND a.start BETWEEN :start AND :end") 

@Entity
public class Task {

@ManyToOne
@JoinColumn(name = "project_id")
private Project project;

@OneToMany(mappedBy = "task")
private List<Activity> activities;

}

Use a .join() . Here is an example from the Criteria API documentation.

For queries that navigate to related entity classes, the query must define a join to the related entity by calling one of the From.join methods on the query root object or another join object. The join methods are similar to the JOIN keyword in JPQL.

The target of the join uses the Metamodel class of type EntityType to specify the persistent field or property of the joined entity.

The join methods return an object of type Join<X, Y>, where X is the source entity and Y is the target of the join. In the following code snippet, Pet is the source entity, Owner is the target, and Pet_ is a statically generated metamodel class:
CriteriaQuery<Pet> cq = cb.createQuery(Pet.class);

Root<Pet> pet = cq.from(Pet.class);
Join<Pet, Owner> owner = pet.join(Pet_.owners);
Joins can be chained together to navigate to related entities of the target entity without having to create a Join instance for each join:
CriteriaQuery<Pet> cq = cb.createQuery(Pet.class);

Root<Pet> pet = cq.from(Pet.class);
Join<Owner, Address> address = cq.join(Pet_.owners).join(Owner_.addresses);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM