【问题标题】:JPA Criteria - where clauseJPA 标准 - where 子句
【发布时间】:2015-10-12 14:54:30
【问题描述】:

我有一个Entity 类,它包含一些原始数据类型,并包含一些具有OneToMany 关系和ManyToOne 关系的对象集合。

当我使用 JPA Criteria 获取数据时,我会获取所有数据,但我想使用 JPA Criteria where clause 过滤结果,我可以应用它的原始数据类型并且它的工作正常,我必须在具有 OneToMany 关系的对象集合中应用 where 子句,有些具有 ManyToOne 关系,但是在这些情况下如何应用 where 子句,你能告诉我吗?

【问题讨论】:

  • 您能否提供实体类的代码,以便我们了解它们之间的关系?另外,请让我们知道您究竟想要检索什么,以便我们为您创建适当的 Criteria 代码。

标签: java hibernate jakarta-ee jpa


【解决方案1】:

使用.join()。这是 Criteria API 文档中的 example

对于导航到相关实体类的查询,查询必须通过调用查询根对象或另一个连接对象上的 From.join 方法之一来定义到相关实体的连接。连接方法类似于 JPQL 中的 JOIN 关键字。

连接的目标使用 EntityType 类型的 Metamodel 类来指定连接实体的持久字段或属性。

连接方法返回一个类型为 Join 的对象,其中 X 是源实体,Y 是连接的目标。在下面的代码sn-p中,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);

【讨论】:

  • 我们将如何应用 where 子句,你能告诉我吗?
【解决方案2】:

我就是这样做的:

存储库

@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 与 Role 相关的 ManyToMany 与员工的 OneToOne 相关。

所以您只需要加入对象并使用设置 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;

}

【讨论】:

  • 我不确定这是否真的回答了 OP 的问题。提到的关于 @OneToMany@ManyToOne 关系的问题,我在您的示例代码中没有看到,而且他说他正在使用标准(不是 JP QL)。
  • 也可以。 JPA 处理关系。 @Query(value = "SELECT a FROM Activity a JOIN a.task t WHERE t.project = :project AND a.start BETWEEN :start AND :end") 这里的活动是 OneToMany 到 Task
  • 是的符合标准,抱歉。我目前有一个代码,但有点大,而且是西班牙语。但我是按照 JPA 的文档构建的。 docs.oracle.com/javaee/6/tutorial/doc/gjivm.html#gjiuvjavamexico.org/blogs/arterzatij/paginacion_datatables_spring
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-10-11
  • 1970-01-01
  • 1970-01-01
  • 2011-01-27
  • 1970-01-01
  • 2011-10-22
  • 2011-06-25
相关资源
最近更新 更多