是否可以通过 ElementCollection 查询 JPA 实体,其中 ElementCollection 包含给定元素集中的所有元素?

Posted

技术标签:

【中文标题】是否可以通过 ElementCollection 查询 JPA 实体,其中 ElementCollection 包含给定元素集中的所有元素?【英文标题】:Is it possible to query JPA entities by ElementCollections where the ElementCollection contains all elements in a given set of elements? 【发布时间】:2015-04-24 16:25:18 【问题描述】:

如何使用 JPQL 通过 ElementCollection 查询 JPA 实体,其中 ElementCollection 包含给定元素集中的所有元素?

例如,如果一个 Node 实体定义了一个 ElementCollection 的 'attributes'

@ElementCollection(fetch=FetchType.EAGER)
@CollectionTable(name="node_attributes", joinColumns=@JoinColumn(name="node_name"))
@MapKeyColumn(name="name")
@Column(name="value")
Map<String, String> attributes = new HashMap<String, String>();

我想查找具有一组给定属性的所有节点实体。我尝试了以下方法,希望“会员”支持收藏。

"SELECT n FROM Node n WHERE :attributes MEMBER OF n.attributes"

此查询始终返回一个空列表。此用例是否可以使用简单的 JPQL 查询?

【问题讨论】:

【参考方案1】:

来自 JPA 2.0 规范,第 4.4.4 章路径表达式

一个标识变量,后跟导航操作符 (.) 和 状态字段或关联字段是一个路径表达式。的类型 路径表达式是作为导航结果计算的类型; 也就是说,状态字段或关联字段的类型 表达式导航。

由 KEY、VALUE 或 ENTRY 限定的标识变量 运算符是路径表达式。 KEY、VALUE 和 ENTRY 运算符可以 仅适用于对应于的标识变量 地图值关联地图值元素集合

使用 ENTRY 运算符的路径表达式是终端。它不可能是 进一步组合,只能出现在查询的 SELECT 列表中。

理论就讲这么多。至于这个问题,我看到三个略有不同的答案,具体取决于您是想通过Map.KeyMap.Value 还是Map.Entry 进行搜索:

String qlKeys = "SELECT DISTINCT n " +
                "FROM Node n JOIN n.attributes a " +
                "WHERE KEY(a) IN :keys";
List<Node> nodes = em.createQuery(qlKeys, Node.class)
                     .setParameter("keys", Arrays.asList("foo", "bar"))
                     .getResultList();
String qlValues = "SELECT DISTINCT n " +
                  "FROM Node n JOIN n.attributes a " +
                  "WHERE VALUE(a) IN :values";
List<Node> nodes = em.createQuery(qlValues, Node.class)
                     .setParameter("values", Arrays.asList("baz", "qux"))
                     .getResultList();

请记住,ENTRY 运算符只能出现在 SELECT 子句中,我们可能必须将其替换为 KEY 和 VALUE 运算符的结合,即

SELECT DISTINCT n 
FROM Node n JOIN n.attributes a
WHERE KEY(a) IN :keys AND VALUE(a) IN :values

在上面的例子中:

标识变量c表示 路径表达式c.attributes表示 关联字段a表示

【讨论】:

以上是关于是否可以通过 ElementCollection 查询 JPA 实体,其中 ElementCollection 包含给定元素集中的所有元素?的主要内容,如果未能解决你的问题,请参考以下文章

对 JP-QL (JPA 2.0) 中的“ElementCollection”映射字段执行“MEMBER OF”查询

@ElementCollection 的 JPA 延迟加载

@OneToMany 和 @ElementCollection 之间的区别?

Hibernate - @ElementCollection - 奇怪的删除/插入行为

可嵌入和 ElementCollection 嵌套

如何在休眠中为@ElementCollection 设置表名