关于使用Hibernate进行集合的IN子句

时间:2015-02-18 10:46:50

标签: hibernate jpa orm hql

我有两个实体:AcknowledgementIndustry。前者与后者有一个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]

此方法适用于其他一些关联类型,但显然不适用于集合。

问题是IN关联的industries子句。我可以写一个原生查询,但我想避免这种情况。如何查找A类型的实体,这些实体具有关联类型为B的对象,其ID在给定集合中?

我希望自己清楚明白。谢谢。

2 个答案:

答案 0 :(得分:2)

尝试下一个查询:

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 ...

答案 1 :(得分:0)

受Andrei的回答启发,我提出了以下查询似乎有效。我之前尝试过,但我遗漏的是DISTINCT函数中的COUNT关键字。与接受的答案相比,我还将联接更改为INNER JOIN,并使用IN上的i.id条款,而不仅仅是别名i

SELECT COUNT(DISTINCT a) FROM Acknowledgement a INNER JOIN a.industries i WHERE a.id IN :acknowledgements AND i.id IN :industries