在CriteriaQuery中使用@ElementCollection(或查询@ElementCollection的内容) [英] Using @ElementCollection in CriteriaQuery (or Querying over the content of an @ElementCollection)

查看:229
本文介绍了在CriteriaQuery中使用@ElementCollection(或查询@ElementCollection的内容)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

public enum ReportStatus { 
    SUCCCEED, FAILED;
}

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

鉴于以下结构,我想执行查询以查找所有内容通过reportStatuses过滤的工作。可以使用以下hql语法正常工作:

Given the following structure, I'd like to perform a query to find all the work filtered by reportStatuses. It works fine with the following hql syntax :

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),并且可以不知道该怎么做。这是我认为最接近的尝试:

But I'd like to use the criteria API (jpa2), and can't figure out how to do it. Here is my closest try I think :

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();
}

我也尝试了休眠标准API,但作为jpa2我找不到正确的语法。

I've also tried with the hibernate criteria API, but as the jpa2 one I've failed to find the correct the syntax.

推荐答案

我将使用以下CriteriaQuery语法来完成相同的工作。

I would use following CriteriaQuery syntax for doing the same thing.

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();



UPDATE



UPDATE


谢谢,但是我们不使用
生成的元模型。很遗憾,
美元,我无法尝试您的答案。 :(

Thanks, but we do not use the generated metamodel. So unfortunately I can't try with your answer. :(

如果您不使用元模型,只需替换 _work.get(Work_.reportStatuses) _work.get( reportStatuses)。它将起作用。:)

If you don't use Metamodel, just replace _work.get(Work_.reportStatuses) with _work.get("reportStatuses"). It'll work. :)

这篇关于在CriteriaQuery中使用@ElementCollection(或查询@ElementCollection的内容)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆