Java Hibernate Criteria Builder:如何按可为空的实体属性进行筛选? 脚本
我有一个实体Java Hibernate Criteria Builder:如何按可为空的实体属性进行筛选? 脚本,java,hibernate,jpa,spring-data-jpa,criteria-api,Java,Hibernate,Jpa,Spring Data Jpa,Criteria Api,我有一个实体治疗,它有两个FK: @ManyToOne @JoinColumn(name = "product_id", nullable = true) private Product product; @ManyToOne @JoinColumn(name = "product2_id", nullable = true) private Product product2; 此产品实体有一个常规id属性作为PK 我想要的是: 我想找到所有产品ID与给定ID匹配的处理方法,在本机SQL中,
治疗
,它有两个FK:
@ManyToOne
@JoinColumn(name = "product_id", nullable = true)
private Product product;
@ManyToOne
@JoinColumn(name = "product2_id", nullable = true)
private Product product2;
此产品
实体有一个常规id属性作为PK
我想要的是:
我想找到所有产品ID与给定ID匹配的处理方法,在本机SQL中,它类似于:
select t.id, product_id,product2_id, p1.category_id,p2.category_id
from Treatment t
left join product p1 on t.product_id=p1.id
left join product p2 on t.product2_id=p2.id
where p1.category_id=17 or p2.category_id=17
Predicate predicate = cb.or(
cb.equal(root.join("product", JoinType.LEFT).get("category"), category),
cb.equal(root.join("product2", JoinType.LEFT).get("category"), category)
);
到目前为止我所做的:
鉴于:
CriteriaQuery<Treatment> cr = cb.createQuery(Treatment.class);
Root<Treatment> root = cr.from(Treatment.class);
但它不起作用:它得到的治疗是两种产品都不为空,并且至少有一种产品符合类别条件
生成的查询是(在清理后使其可读):
这应该起作用:
Predicate predicate = (root1, cq1, cb1) -> Specifications.where(
cb1.equal(root1.get("product").get("category"), category)).or(
cb1.equal(root1.get("product2").get("category"), category))
.toPredicate(root, cb, cq);
尝试使用#join中的
构建路径,您可以在其中明确定义连接类型,例如:
select t.id, product_id,product2_id, p1.category_id,p2.category_id
from Treatment t
left join product p1 on t.product_id=p1.id
left join product p2 on t.product2_id=p2.id
where p1.category_id=17 or p2.category_id=17
Predicate predicate = cb.or(
cb.equal(root.join("product", JoinType.LEFT).get("category"), category),
cb.equal(root.join("product2", JoinType.LEFT).get("category"), category)
);
据我所知,您可以使用条件自己执行连接createAlias()
似乎是@XtremeBaumer的发展方向,我正在使用Hibernate 5及其新的CriteriaBuilder API。链接的示例生成警告(不推荐的类),因为它是旧的API。我想我遗漏了一些东西:我应该把这个lambda放在哪里?你是对的,我没有澄清它。它返回谓词,所以它应该放在谓词内部。(我更新了答案)对不起,但是javax.persistence.criteria.Predicate
在javax.persistence-api-2.2中不是一个函数接口,我相信@Alex的答案是正确的。键是左连接.toPredicate(root、cb、cq)代码>传递您之前定义的根、cb、cq