是否可以通过 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.Key
、Map.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”查询
@OneToMany 和 @ElementCollection 之间的区别?