2012-04-19 15 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")) 
);