6
public enum ReportStatus { 
    SUCCCEED, FAILED;
}

public class Work {
    @ElementCollection
    @Enumerated(EnumType.STRING)
    List<ReportStatus> reportStatuses;
}

次の構造を前提として、reportStatusesによってフィルタリングされたすべての作業を見つけるためにクエリを実行したいと思います。次のhql構文で正常に動作します。

public List<Long> queryHQL() {
    final String query = "SELECT w.id FROM Work w JOIN w.reportStatuses s WHERE s in (:rs)";

    final List<ReportStatus> reportStatuses = new ArrayList<ReportStatus>();
    reportStatuses.add(ReportStatus.FAILED);

    return this.entityManager.createQuery(query).setParameter("rs", reportStatuses).getResultList();
}

しかし、基準API(jpa2)を使用したいのですが、その方法がわかりません。これが私の最も近い試みです:

public List<Long> query() {
    final List<ReportStatus> reportStatuses = new ArrayList<ReportStatus>();
    reportStatuses.add(ReportStatus.FAILED);

    final CriteriaBuilder builder = this.entityManager.getCriteriaBuilder();

    final CriteriaQuery<Long> criteriaQuery = builder.createQuery(Long.class);
    final Root<Work> workModel = criteriaQuery.from(Work.class);

    final ListJoin<Work, ReportStatus> status = workModel.joinList("reportStatuses");

    final Predicate predicate = status.in(reportStatuses);

    criteriaQuery.where(predicate);
    criteriaQuery.select(workModel.<Long> get("id"));

    return this.entityManager.createQuery(criteriaQuery).getResultList();
}

Hibernate基準APIも試しましたが、jpa2として、正しい構文を見つけることができませんでした。

4

3 に答える 3

5

同じことを行うには、次の CriteriaQuery 構文を使用します。

EntityManager em = entityManagerFactory.createEntityManager();

final List<ReportStatus> reportStatuses = new ArrayList<ReportStatus>();
reportStatuses.add(ReportStatus.FAILED);

final CriteriaBuilder builder = em.getCriteriaBuilder();

final CriteriaQuery<Long> criteriaQuery = builder.createQuery(Long.class);
final Root<Work> _work = criteriaQuery.from(Work.class);

/*final ListJoin<Work, ReportStatus> status = _work.joinList("reportStatuses");
final Predicate predicate = status.in(reportStatuses);
criteriaQuery.where(predicate);*/

final Expression<List<ReportStatus>> _status = _work.get(Work_.reportStatuses);
_status.in(reportStatuses);

criteriaQuery.select(_work.get(Work_.id));

List<Long> list =  em.createQuery(criteriaQuery).getResultList();

アップデート

ありがとうございます。ただし、生成されたメタモデルは使用しません。残念ながら、私はあなたの答えを試すことができません。:(

Metamodel を使用しない場合は、 に置き換え_work.get(Work_.reportStatuses)_work.get("reportStatuses")ください。うまくいきます。:)

于 2010-12-09T16:47:35.460 に答える
3

この HQL を作成できます。

String query = "SELECT w.id FROM Work w, IN(w.reportStatuses) s WHERE s = :rs";
return this.entityManager.createQuery(query).setParameter("rs", ReportStatus.FAILED).getResultList();
于 2011-08-20T21:12:17.907 に答える
1

よくわかりません。への呼び出しin(..)は述語を返しますが、実際にはそれを強制していないようです (クエリに統合されているようには見えません。少なくとも私にとっては、コレクションが と交差しているかどうかに関係なく、ルートのすべてのメンバーが返されましたreportStatuses。デバッグ ログ簡単なクエリを示しますselect distinct work0_.id as id18_ from Work work0_)。

また、呼び出し元が 1 つの値に一致するものだけに関心がある場合、わざわざ reportStatuses をリストに入れる必要はありません。ReportStatus.FAILEDリストを作成する代わりに、使用するだけでどのようにクエリを実行しますか?

于 2011-07-05T15:59:33.740 に答える