2012-05-06 19 views
12

契約が有効かどうかを1年間確認する休止状態を作成しています。契約の開始日と終了日は標準の日付フィールドになります。Hibernate Criteria抽出年から日付

だからSQL-SERVERに使用されて、私はこのSQLの行で何かを思うだろう:

SELECT * FROM CONTRACT WHERE YEAR(startDate) <= ? AND YEAR(endDate) >= ? 

questionmarkが整数として与えられた年です。

どのようにこれを休止状態の基準に変換するのですか?

int year = 2011; //Just a testyear for example purposes. 
DetachedCriteria criteria = DetachedCriteria.forClass(Contract.class) 
    .add(Restrictions.le("startDate", year)) 
    .add(Restrictions.ge("endDate", year)); 

ご覧のとおり、比較できるように、日付を1年に変換するビットがありません。もちろん、私のコードはそのまま実行されません。

希望の結果を得るための提案はありますか?あなたの問題は解決します

答えて

13

それは直接あなたが望んでサポートされていないAPIのように見えるが、あなたは検討するかもしれない回避策があります。

解決方法1:二つの方法の

DetachedCriteria criteria = DetachedCriteria.forClass(Contract.class) 
    .add(Restrictions.le("startDate", toEndOfYear(year)) 
    .add(Restrictions.ge("endDate", toStartOfYear(year))); 

public Date toStartOfYear(int year) { 
    Calendar calendar = Calendar.getInstance(); 
    calendar.set(Calendar.YEAR, year); 
    calendar.set(Calendar.DAY_OF_YEAR, 0); 
    calendar.set(Calendar.HOUR_OF_DAY, 0); 
    calendar.set(Calendar.MINUTE, 0); 
    calendar.set(Calendar.SECOND, 0); 
    return calendar.getTime(); 
} 

public Date toEndOfYear(int year) { 
    Calendar calendar = Calendar.getInstance(); 
    calendar.set(Calendar.YEAR, year); 
    calendar.set(Calendar.DAY_OF_YEAR, 0); 
    calendar.set(Calendar.HOUR_OF_DAY, 0); 
    calendar.set(Calendar.MINUTE, 0); 
    calendar.set(Calendar.SECOND,-1); 
    return calendar.getTime(); 
} 

出力例:

System.out.println(toStartOfYear(2013)); 
System.out.println(toEndOfYear(2013)); 

Mon Dec 31 00:00:00 MYT 2012 
Sun Dec 30 23:59:59 MYT 2012 

解決方法2:

DetachedCriteria criteria = DetachedCriteria.forClass(Contract.class) 
    .add(Restrictions.sqlRestriction("YEAR(startDate) >= ? ", year,Hibernate.INTEGER)) 
    .add(Restrictions.sqlRestriction("YEAR(endDate) <= ? ", year,Hibernate.INTEGER)); 
+1

'toEndOfYear'方法は、に1を追加する必要がありますけれどもソリューション1は、素敵なきれいな代替手段ですyearが 'cal.set'に渡されると、それ以外の場合は前年の終わりを得ます – Numeron

5

使用Restrictions.sqlRestriction

3

あなたはJPA criteriaBuilderを使用する場合は、することができますを使用するメソッド。例えば。

contractRepository.findAll(new Specification<Contract>() { 
    @Override 
    public Predicate toPredicate(Root<Contract> root, CriteriaQuery<?> query, CriteriaBuilder cb) { 
    return cb.ge(cb.function("year", Integer.class, root.get(Contract_.endDate)), year); 
    } 
}); 

(私はデータベースを照会するために、この例では春データSpecificationsを使用しています。contractRepositoryはタイプJpaSpecificationExecutorのことである)