2012-04-19 14 views
1

我想建立一个查询,查询不同实体的日期。我的结构是:如果JPA Criteria Builder中的/ Case语句为

  • 合同日期(非可空)
  • 员工都有日期(非可空)
  • 雇员可能有一个合同号(可为空)

如果一个员工都有合同我想检索合同日期。如果员工没有合同,那么我想要返回员工日期。

到目前为止我的代码是:

if (inputDate!= null) { 
    ParameterExpression<Date> exp = criteriaBuilder.parameter(Date.class, "inputDate"); 
    criteria.add(criteriaBuilder.or(
     criteriaBuilder.isNull(employee.get("contract")), 
     criteriaBuilder.lessThanOrEqualTo(employee.<Date>get("creationDate"), exp), criteriaBuilder.lessThanOrEqualTo((employee.join("contract").<Date>get("fromDate")), exp)));} 

这似乎并没有工作,虽然。我总是看起来进入了我并不期待的isNull。

我很高兴看到这一些更多,但我想我的问题是这是否是正确的方式去实现它。是吗?我在criteriaBuilder中看到了一个selectCase,所以也许这可能是一个更好的解决方案。

任何指针都会被大量接收。

感谢

回答

3

这里将是一个解决方案,不知道它的工作原理,但我们会设法得到它在您的帮助:)工作:

ParameterExpression<Date> inputDateExp = criteriaBuilder.parameter(Date.class, "inputDate"); 
Predicate employeeCreationDate = criteriaBuilder.lessThanOrEqualTo(
     employee.<Date>get("creationDate"), inputDateExp); 
Predicate contractStartDate = criteriaBuilder.lessThanOrEqualTo(
     employee.join("contract").<Date>get("fromDate"), inputDateExp); 

criteria.add(
     criteriaBuilder.selectCase().when(employee.get("contract").isNull(), employeeCreationDate).otherwise(contractStartDate)); 

我不明白,为什么用“inputDate “作为表达而不是日期?另外,我建议将criteria重命名为ccriteriaBuildercb,这样可以节省空间,我认为它更舒适。

+0

嗨JMelnik,感谢您的回复。我在这段代码中遇到的问题是selectCase返回一个表达式而不是谓词。它实际上是返回谓词,所以试图将整个事件作为谓词来处理。不幸的是,它仍然不能编译,因为我正在投射,所以我觉得很奇怪。你知道这可能是什么吗?谢谢 – RNJ 2012-04-23 09:49:59

+0

@ user846476我认为我们需要做的是比较日期和Case语句中的日期。 – JMelnik 2012-06-14 06:38:48

0

我想你想要做的是使用Case<Date>,并使用Predicate仅作为Case#when的第一个参数。 Case<Date>是一个Expression<Date>,这是你想要通过CriteriaQuery#multiselect

CriteriaQuery<Employee> query = criteriaBuilder.createQuery(Employee.class); 
Root<Employee> employee = query.from(Employee.class); 
query.multiselect 
(
    criteriaBuilder.selectCase() 
     .when(criteriaBuilder.isNull(employee.get("contract")), employee.get("creationDate")) 
     .otherwise(employee.join("contract").get("fromDate")) 
);