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

标签 java orm jpa-2.0 criteria-api

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 criteria API,但是作为 jpa2,我没能找到正确的语法。

最佳答案

我会使用以下 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();

更新

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

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

关于java - 在 CriteriaQuery 中使用 @ElementCollection(或查询 @ElementCollection 的内容),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3892851/

相关文章:

java - JavaCL 和 JogAmp JOCL 比较如何?

java - 使用 MyBatis 动态列名与 where 子句中的值进行比较

hibernate - 在 JBoss AS 7 中捕获由 hibernate JPA 生成的最终 SQL 查询

java - 多个数据输入/输出流混淆

java - java.io.File 中 mkdir() 和 mkdirs() 的区别

orm - Dapper.Rainbow VS Dapper.Contrib

jpa-2.0 - 级联 Type.ALL 不起作用

java - 在 JPA 中的各个列上使用 DISTINCT 关键字

java - 导出为CSV编码问题

javascript - 无法使用 Sequelize (nodejs) 连接到本地主机数据库