Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/352.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Hibernate Criteria Builder:如何按可为空的实体属性进行筛选? 脚本_Java_Hibernate_Jpa_Spring Data Jpa_Criteria Api - Fatal编程技术网

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