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,这意味着我们有一个单向的一对多关系。我需要寻找一个POSbyposId和supplierId。即,找到具有指定的供应商,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 对象。
| 归档时间: |
|
| 查看次数: |
9685 次 |
| 最近记录: |