当前位置: 首页 > 知识库问答 >
问题:

JoinTable上的JPA条件子查询

常自强
2023-03-14

如何创建高效的 JPA 条件查询,以便仅当实体存在于联接表中时才选择实体列表?例如,采用以下三个表:

create table user (user_id int, lastname varchar(64));
create table workgroup (workgroup_id int, name varchar(64));
create table user_workgroup (user_id int, workgroup_id int); -- Join Table

有问题的查询(我希望 JPA 生成什么)是:

select * from user where user_id in (select user_id from user_workgroup where workgroup_id = ?);

以下条件查询将产生类似的结果,但有两个连接:

    CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
    CriteriaQuery<User> cq = cb.createQuery(User.class);
    Root<User> root = cq.from(User.class);
    cq.select(root);

    Subquery<Long> subquery = cq.subquery(Long.class);
    Root<User> subroot = subquery.from(User.class);
    subquery.select(subroot.<Long>get("userId"));
    Join<User, Workgroup> workgroupList = subroot.join("workgroupList");
    subquery.where(cb.equal(workgroupList.get("workgroupId"), ?));
    cq.where(cb.in(root.get("userId")).value(subquery));

    getEntityManager().createQuery(cq).getResultList();

根本问题似乎是我对USER_WORKGROUP连接表使用@JoinTable注释,而不是对连接表使用单独的@Entity,所以我似乎不能在条件查询中将USER_WORGGroup用作根。

以下是实体类:

@Entity
public class User {
  @Id
  @Column(name = "USER_ID")
  private Long userId;
  @Column(name = "LASTNAME")
  private String lastname;
  @ManyToMany(mappedBy = "userList")
  private List<Workgroup> workgroupList;
}

@Entity
public class Workgroup {
  @Id
  @Column(name = "WORKGROUP_ID")
  private Long workgroupId;
  @Column(name = "NAME")
  private String name;
  @JoinTable(name = "USER_WORKGROUP", joinColumns = {
        @JoinColumn(name = "WORKGROUP_ID", referencedColumnName = "WORKGROUP_ID", nullable = false)}, inverseJoinColumns = {
        @JoinColumn(name = "USER_ID", referencedColumnName = "USER_ID", nullable = false)})
  @ManyToMany
  private List<User> userList;
}

共有1个答案

冯阳成
2023-03-14

据我所知,JPA基本上忽略了联接表。您所做的JPQL将是

select distinct u from user u join u.workgroupList wg where wg.name = :wgName

对于条件查询,您应该能够:

Criteria c = session.createCriteria(User.class, "u");
c.createAlias("u.workgroupList", "wg");
c.add(Restrictions.eq("wg.name", groupName));
c.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

不必担心中间的联接表。

 类似资料:
  • 问题内容: 我花了几个小时进行搜索,没有发现与我的案子相似的内容。 让我们假设以下多对多数据模型: 现在,假设我要映射与合同方(单向)有关的 所有 合同。可以使用实体类中的以下注释来完成: 那样就好。 但是我要寻找的是如何映射具有 特定角色的 合同? 从技术上讲,我正在寻找一种在JOIN语句中添加 额外条件 的方法。 到目前为止,在类似的主题中发现了以下想法: 将联接表映射为单独的实体,并使用自定

  • 显然,扩展了,是抽象的,继承是, 和 具有 其他原因 。 但生成的SQL是这样的: 在我期待的时候: 请注意 使用另一根- 使用子查询- 将lastName字段上移到主题 使用本机查询 使用实体图 是不能接受的。 我感兴趣的是可以在WHERE子句中直接声明和使用的东西(仅从CriteriaBuilder和/或单个Root生成,就像子句一样)(如果确实存在的话)。

  • 我正在努力使用JPA标准API来为我的数据结构制定一个查询。好的,我的实体如下。我有用户和组(两者共享一个公共的基类OrgEntity)。从逻辑上讲,用户当然可以是多个组中的成员。最后,我有一个表示任务的实体,它有一个潜在所有者的列表(可以是单个用户,也可以是整个组)。域模型总结在下面,是给出的,所以我不能改变它。 查询的起点是User的单个实例。我想知道用户是潜在所有者的所有任务(无论用户是直接

  • 我有两张桌子“table1”和“table2”。对于表1中的每一行,表2中可以有多行 和 然后我创建了这样的存储库 这将给出表1中按公司ID列出的行列表,以及表2中具有相应供应商ID的行列表。 到目前为止,我的实现工作正常。 答案是 目前,我以companyId作为输入,并给出了上述响应。现在我想把cityId作为一个输入。因此,表2的输出应该只包含给定cityId的详细信息。 那么,有谁能帮助我

  • 现在我扪心自问,是不是有什么“点符号”或者其他什么东西让这个案例变得可有可无。在E。例如:本机SQL我会做一些事情,比如创建一个子查询,并从内部投影中选择所有别名值()。 如果有任何建议,我将不胜感激。