我有一个Entity
类,它包含一些原始数据类型,并包含一些具有OneToMany
关系和ManyToOne
关系的对象集合。
当我使用JPA Criteria
获取数据时,我得到所有数据,但我想使用JPA Criteria where clause
过滤结果,我可以应用其原始数据类型,并且其工作正常,我必须在具有OneToMany
关系的对象集合中应用where子句,其中一些具有ManyToOne关系,但如何在这些情况下应用where子句,你能告诉我吗?
答案 0 :(得分:0)
我是这样做的:
存储库
@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与ManyToMany相关,其中OneToOne与员工有关。
所以你只需要加入Object并使用设置PKEY(ID)的对象进行过滤。
实体
@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;
}
另一种关系
@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;
}
答案 1 :(得分:0)
使用.join()
。以下是Criteria API文档中的example。
对于导航到相关实体类的查询,查询必须通过调用查询根对象或另一个连接对象上的一个From.join方法来定义与相关实体的连接。连接方法类似于JPQL中的JOIN关键字。
连接的目标使用EntityType类型的Metamodel类来指定连接实体的持久字段或属性。
join方法返回Join&lt; X,Y&gt;类型的对象,其中X是源实体,Y是连接的目标。在以下代码片段中,Pet是源实体,Owner是目标,Pet_是静态生成的元模型类:
CriteriaQuery<Pet> cq = cb.createQuery(Pet.class);
Root<Pet> pet = cq.from(Pet.class);
Join<Pet, Owner> owner = pet.join(Pet_.owners);
可以将联接链接在一起以导航到目标实体的相关实体,而无需为每个联接创建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);