【问题标题】:Is it possible to query JPA entities by ElementCollections where the ElementCollection contains all elements in a given set of elements?是否可以通过 ElementCollection 查询 JPA 实体,其中 ElementCollection 包含给定元素集中的所有元素?
【发布时间】: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 查询?

【问题讨论】:

    标签: jpa jpql jpa-2.1


    【解决方案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表示

    【讨论】:

      猜你喜欢
      • 2013-01-21
      • 2019-11-03
      • 1970-01-01
      • 2016-05-13
      • 1970-01-01
      • 1970-01-01
      • 2015-06-16
      • 2010-11-08
      • 2020-04-10
      相关资源
      最近更新 更多