java - 如何使用 JPA 的标准 API 构造多列 "WHERE ... IN"表达式?

标签 java jpa-2.0 eclipselink criteria-api

对于具有多列 ID 的实体,我们需要将所有那些尚未存在于数据库中的对象保存在给定列表中。由于要检查的对象数量很大,并且存储中的对象数量可能非常大,因此想法是使用它们的多列私钥和“WHERE ... IN (. ..)"使用标准 API 构造的类型语句,以便它们可以在持久化之前从列表中删除。

这是尝试执行此操作的代码:

    public void persistUnique(List<CdrEntity> cdrs) {
        // find all the CDRs in the collection that are already in the DB
        CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
        CriteriaQuery<CdrEntity> query = criteriaBuilder.createQuery(CdrEntity.class);
        Root<CdrEntity> cdrRoot = query.from(CdrEntity.class);
        query.select(cdrRoot).where(cdrRoot.in(cdrs));
        List<CdrEntity> nonUnique = entityManager.createQuery(query).getResultList();
        // remove nonUnique elements from crds and persist
        ...
    }

但是,至少使用 EclipseLink 2.4.1,这是实际发送到数据库的内容(为了便于阅读省略了一些输出):

[EL Fine]: sql:...--SELECT SUBINDEX, ... FROM CDRS WHERE ((?, ?, ?, ?) IN ((?, ?, ?, ?), (?, ?, ?, ?), ...))
bind => [null, null, null, null, 2, 1362400759, 19415, 176, ...]

本质上,在主键列的适当列名应该出现的地方,添加了一些参数并稍后绑定(bind)(值为 null)。除此之外,查询没问题,如果前四个 ?s 被实际的列名替换,则执行得到所需的结果。

然而,直接在 Root 上调用 .in(...) 似乎没有预期的结果。如果不能直接使用实体,我希望有某种 Expression 可以代表多个列,然后可以成为调用 .in(... ),但我一直找不到。

因此,问题是:如何正确地做到这一点?还是 JPA 根本不可能?或者只是 EclipseLink 中存在错误?

最佳答案

有趣的尝试,并且生成了奇怪的 SQL,SQL 看起来左边是正确的,但右边不是。请为此记录一个错误,这是可以支持的。 (也可以在 2.5 开发版本中尝试,它可能会起作用)。

JPA Criteria API 不支持嵌套数组,因此这超出了 JPA 规范。

您可以为左侧的 id 字段创建一个路径表达式列表,并为此使用 CriteriaBuilder literal() 表达式,它可能会起作用。

执行此操作的 JPA 标准方法是遍历对象列表和表达式中的 or() 以比较每个对象的 ID。

关于java - 如何使用 JPA 的标准 API 构造多列 "WHERE ... IN"表达式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15205841/

相关文章:

java - 在 WebSphere 中注入(inject) spring 资源失败

java - 为什么接受接口(interface)的方法会拒绝该接口(interface)的实现?

java - 获取节点子节点时 Android Firebase 实时数据库错误

hibernate - 没有persistence.xml的Spring 3.1给出 "Unable to resolve persistence unit root URL"

java - 用于创建和更新时间戳的触发器与 JPA @PrePersist 的优缺点

Java - 比较线性搜索和二分搜索的性能

spring-data - H2 Spring-Data - 默认值不起作用

java - EclipseLink 分布式缓存导致主键为空,什么?

jpa - EclipseLink 中的多个可写映射异常

web-services - 没有无限循环的 JAX WS 服务上的 Jpa 实体