单向一对多关系的条件查询

Dan*_*sev 3 hibernate one-to-many criteria-api

所以,我有以下实体:

@Entity
public class Supplier {
    @Column(name = "SUPPLIERID")
    private BigInteger supplierId;

    @OneToMany
    @JoinColumn(name = "ID_SUPP", foreignKey = @ForeignKey(name = "fk_POIS_SUPP"))
    private List<POS> posList;

    ...
}

@Entity
public class POS {
    @Column(name = "POSID")
    private BigInteger posId
}
Run Code Online (Sandbox Code Playgroud)

所以,POS没有对 的引用Supplier,这意味着我们有一个单向的一对多关系。我需要寻找一个POSbyposIdsupplierId。即,找到具有指定的供应商,supplierId然后在供应商的 pos 列表中找到具有指定 posId 的 pos。我如何为此编写条件查询?

我尝试使用子查询。我的想法是创建一个子查询可以取所有POS“的小号Supplier与给定的supplierId。然后主查询将在这些POS's 中搜索POS具有给定的 a posId

问题是我无法编写一个查询来获取Suppliers 的 s 列表POS。显然你不能写一个类型的查询List<POS>

CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<POS> outerQuery = cb.createQuery(POS.class);
Root<POS> outerQueryRoot = outerQuery.from(POS.class);

Subquery<POS> subquery = outerQuery.subquery(POS.class);
Root<Supplier> subqueryRoot = subquery.from(Supplier.class);
subquery.where(cb.equal(subqueryRoot.get(Supplier_.supplierId), supplierId));
subquery.select(subqueryRoot.get(Supplier_.posList);
Run Code Online (Sandbox Code Playgroud)

在最后一行中,我收到一个编译错误Expression<POS> does not match Expression<List<POS>>. 而且我无法更改子查询的类型,因为 Java 不允许使用泛型类文字 ( List<POS>.class)。

有任何想法吗?

小智 7

我找到了没有子查询的非常简单的解决方案。从Suppler开始,通过posList加入POS,然后'select'POS。

CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<POS> query = cb.createQuery(POS.class);

Root<Supplier> supplierRoot = query.from(Supplier.class);
ListJoin<Supplier, POS> posList = supplierRoot.joinList(Supplier_.posList);
query
    .select(posList)
    .where(
        cb.equal(supplierRoot.get(Supplier_.suppliertId), supplierId),
        cb.equal(posList.get(POS_.posId), posId)
    );
Run Code Online (Sandbox Code Playgroud)

使用 Hibernate 5.2.11,它通过 N->M 表生成了两个内部连接的很好的查询,非常类似于手动编写的代码;-)。接受的答案是我猜错了,因为它跳过了“posList”关系。它将选择与指定供应商无关的 POS 对象。