2017-01-16 5 views
1

古いHibernate(SessionFactory beanを利用しています)で記述するクエリがあります。しかし、私はSpring Bootに移行し、JPA 2を利用しています。JPA 2は基本的にHibernate上の抽象レイヤーのようです。どのように制限を追加する方法について私を導く人はいますか? JPAにEntityManager beanを使用する必要があると私は考えています。ここに古いクエリがあります。日付制約を含むJPA2を使用してEntityMangerを使用してHibernate SessionFactoryクエリを書き換える

@Override 
@SuppressWarnings("unchecked") 
public List<Party> queryPartiesBetweenDates(Date startDate, Date endDate, String sortBy, Integer count) { 
    Criteria criteria = getCurrentSession().createCriteria(Party.class); 
    if (startDate != null) { 
     criteria.add(Restrictions.ge("startDate", startDate)); 
    } 
    if (endDate != null) { 
     criteria.add(Restrictions.lt("endDate", endDate)); 
    } 
    if (count != null) { 
     criteria.setMaxResults(count); 
    } 
    if (sortBy == null || !sortBy.equals("distance")) { 
     criteria.addOrder(Order.asc("startDate")); 
    } 
    return criteria.list(); 
} 

ありがとう!

+1

これが役に立ちます。 https://www.jumpingbean.co.za/blogs/jpa2-criteria-api – Jobin

答えて

1

CriteriaBuilderは、ネイティブのHibernate Restriction APIよりもかなり冗長です。主な理由は、MetaModelを使用すると完全に型指定されます。つまり、列の型または名前が原因でコンパイルされません。無効となるクエリ。 ここでは、生成されたMetaModelクラスを使用せず、ほとんどの場合古いHibernateコードに似ている例を示します。あなたは多くの述語を持っている場合は

EntityManager em = emf.createEntityManager(); // or injected 

CriteriaBuilder cb = em.getCriteriaBuilder(); 
CriteriaQuery<Party> query = cb.createQuery(Party.class); 
Root<Party> partyRoot = query.from(Party.class); 
query.select(partyRoot); 

Predicate predicate = null; 
Path<Date> startDatePath = partyRoot.<Date>get("startDate"); 
if (startDate != null) { 
    predicate = cb.greaterThanOrEqualTo(startDatePath, startDate); 
} 
if (endDate != null) { 
    Predicate additionalPredicate = cb.lessThanOrEqualTo(partyRoot.<Date>get("endDate"), startDate); 
    if (predicate == null) { 
     predicate = additionalPredicate; 
    } else { 
     predicate = cb.and(predicate, additionalPredicate); 
    } 
} 
query.where(predicate); 

if (sortBy == null || !sortBy.equals("distance")) { 
    query.orderBy(cb.asc(startDatePath)); 
} 

return em.createQuery(query).setMaxResults(count).getResultList(); 

は、リストに追加、またはそれらを処理するためのユーティリティメソッドを作成するために、良いアイデアかもしれません。

+0

ありがとうございました!!! – tsaebeht

+0

メタモードクラスの使用をバイパスする方法が好きでした。ほとんどすべてのクエリは、このようにメタモードクラスなしで記述できますか? – tsaebeht

+1

フィールド名がわかっている限り、静的メタモデルは必要ありません。 '' Path''と '' Expression''は非常に一般的なので、Root.get()からの戻り値をキャストする必要があります。フィールドがコレクション要素を参照することが必要な場合があります。結合構文に使用できます。しかし、最良の選択肢は、(静的な)メタモデルを生成することです(アノテーション処理)。これは '' 'Party_'''という名前のクラスを生成します.''''Party_.startDate'''を使って取得することができますパス、それから完全に型の安全です。 –

関連する問題