在CriteriaQuery中使用@ElementCollection(或查询@ElementCollection的内容)

Rap*_*ier 6 java orm criteria-api jpa-2.0

public enum ReportStatus { 
    SUCCCEED, FAILED;
}

public class Work {
    @ElementCollection
    @Enumerated(EnumType.STRING)
    List<ReportStatus> reportStatuses;
}
Run Code Online (Sandbox Code Playgroud)

鉴于以下结构,我想执行查询以查找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();
}
Run Code Online (Sandbox Code Playgroud)

但是我想使用标准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();
}
Run Code Online (Sandbox Code Playgroud)

我也尝试过使用hibernate标准API,但作为jpa2,我没能找到正确的语法.

dir*_*ira 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();
Run Code Online (Sandbox Code Playgroud)

UPDATE

谢谢,但我们不使用生成的元模型.所以不幸的是我不能尝试你的答案.:(

如果您不使用Metamodel,只需替换_work.get(Work_.reportStatuses)_work.get("reportStatuses").它会工作的.:)