使用 Hibernate 收集的 IN 子句
IN clause on collection with Hibernate
我有两个实体:Acknowledgement
和 Industry
。前者与后者有 ManyToMany 关联,反之亦然。
@Entity
public class Acknowledgement {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column
private int id;
@ManyToMany
@JoinTable(name = "acknowledgement_industry", joinColumns = @JoinColumn(name = "acknowledgement_id"), inverseJoinColumns = @JoinColumn(name = "industry_id"))
private Set<Industry> industries = new HashSet<>();
}
@Entity
public class Industry {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column
private int id;
@ManyToMany(mappedBy = "industries")
private Set<Acknowledgement> acknowledgements = new HashSet<>();
}
我正在尝试创建一个 JPQL/HQL 查询,它根据一组 ID 查找致谢,这些 ID 还与一组行业 ID 相关联 - 并使用聚合函数 count
。所以我想知道有多少满足这些条件的致谢。这是我尝试过的一些方法:
long result = (long) this.getEntityManager()
.createQuery(jpql)
.setParameter("acknowledgements", new HashSet<>(acknowledgementIds))
.setParameter("industries", new HashSet<>(industryIds))
.getSingleResult();
参数是整数集。我也尝试使用实体对象。对于 jpql
字符串,我尝试了以下查询(以及一些变体)。
查询#1
select count(a) from Acknowledgement a where a.id in :acknowledgements and a.industries in :industries
结果
org.postgresql.util.PSQLException: No value specified for parameter 2.
查询 #2
select count(a) from Acknowledgement a where a.id in :acknowledgements and a.industries.id in :industries
结果
org.hibernate.QueryException: illegal attempt to dereference collection [acknowledg0_.id.industries] with element property reference [id]
这种方法适用于其他一些关联类型,但显然不适用于集合。
问题是 industries
关联的 IN
子句。我可以编写本机查询,但我想避免这种情况。如何找到 A
类型的实体,这些实体具有关联的 B
类型的对象,其 ID 在给定集中?
我希望我说清楚了。谢谢。
尝试下一个查询:
SELECT COUNT( DISTINCT a) FROM Acknowledgement a INNER JOIN a.industries AS ind where a.id in :acknowledgements and ind.id IN :industries
或者您可以使用 MEMBER OF
代替 IN
表达式:WHERE :industry1 MEMBER OF a.industries OR :industry2 MEMBER OF a.industries OR ...
.
受安德烈回答的启发,我提出了以下似乎有效的查询。我之前曾尝试过,但我缺少的是 COUNT
函数中的 DISTINCT
关键字。与接受的答案相比,我还将连接更改为 INNER JOIN
并在 i.id
上使用了 IN
子句,而不仅仅是别名 i
.
SELECT COUNT(DISTINCT a) FROM Acknowledgement a INNER JOIN a.industries i WHERE a.id IN :acknowledgements AND i.id IN :industries
我有两个实体:Acknowledgement
和 Industry
。前者与后者有 ManyToMany 关联,反之亦然。
@Entity
public class Acknowledgement {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column
private int id;
@ManyToMany
@JoinTable(name = "acknowledgement_industry", joinColumns = @JoinColumn(name = "acknowledgement_id"), inverseJoinColumns = @JoinColumn(name = "industry_id"))
private Set<Industry> industries = new HashSet<>();
}
@Entity
public class Industry {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column
private int id;
@ManyToMany(mappedBy = "industries")
private Set<Acknowledgement> acknowledgements = new HashSet<>();
}
我正在尝试创建一个 JPQL/HQL 查询,它根据一组 ID 查找致谢,这些 ID 还与一组行业 ID 相关联 - 并使用聚合函数 count
。所以我想知道有多少满足这些条件的致谢。这是我尝试过的一些方法:
long result = (long) this.getEntityManager()
.createQuery(jpql)
.setParameter("acknowledgements", new HashSet<>(acknowledgementIds))
.setParameter("industries", new HashSet<>(industryIds))
.getSingleResult();
参数是整数集。我也尝试使用实体对象。对于 jpql
字符串,我尝试了以下查询(以及一些变体)。
查询#1
select count(a) from Acknowledgement a where a.id in :acknowledgements and a.industries in :industries
结果
org.postgresql.util.PSQLException: No value specified for parameter 2.
查询 #2
select count(a) from Acknowledgement a where a.id in :acknowledgements and a.industries.id in :industries
结果
org.hibernate.QueryException: illegal attempt to dereference collection [acknowledg0_.id.industries] with element property reference [id]
这种方法适用于其他一些关联类型,但显然不适用于集合。
问题是 industries
关联的 IN
子句。我可以编写本机查询,但我想避免这种情况。如何找到 A
类型的实体,这些实体具有关联的 B
类型的对象,其 ID 在给定集中?
我希望我说清楚了。谢谢。
尝试下一个查询:
SELECT COUNT( DISTINCT a) FROM Acknowledgement a INNER JOIN a.industries AS ind where a.id in :acknowledgements and ind.id IN :industries
或者您可以使用 MEMBER OF
代替 IN
表达式:WHERE :industry1 MEMBER OF a.industries OR :industry2 MEMBER OF a.industries OR ...
.
受安德烈回答的启发,我提出了以下似乎有效的查询。我之前曾尝试过,但我缺少的是 COUNT
函数中的 DISTINCT
关键字。与接受的答案相比,我还将连接更改为 INNER JOIN
并在 i.id
上使用了 IN
子句,而不仅仅是别名 i
.
SELECT COUNT(DISTINCT a) FROM Acknowledgement a INNER JOIN a.industries i WHERE a.id IN :acknowledgements AND i.id IN :industries