【问题标题】:Why does compare of entities not work in subquery为什么实体比较在子查询中不起作用
【发布时间】:2013-09-01 12:40:55
【问题描述】:

谁能解释一下,为什么这个查询在 JPA 中有效:

SELECT e FROM Entry e JOIN e.tags tags WHERE tags IN :tags 

e.tags 是

@ManyToMany(mappedBy = "entryList" )
private List<Tag> tags = new LinkedList<>();

所以,我可以将标签中的实体与参数中的实体进行比较。但以下不起作用:

SELECT e FROM Entry e WHERE (SELECT COUNT(t) FROM Tag t JOIN t.entryList e2 WHERE e2 = e AND t IN :tags) = :size

没有错误,但没有找到结果。如果我将标签 ID 列表提供给参数 :tags 并执行以下查询,则它可以正常工作:

SELECT e FROM Entry e WHERE (SELECT COUNT(t) FROM Tag t JOIN t.entryList e2 WHERE e2 = e AND t.id IN :tagIds) = :size

我花了几个小时才找到这个简单的错误原因,并且想知道什么时候可以比较实体,什么时候不可以?

【问题讨论】:

    标签: java jpa entity jpa-2.0


    【解决方案1】:

    我不认为 JPA soec 允许 IN 中的对象。一些提供程序可能会,但这可能取决于您使用的版本、您的对象是否具有复合 ID 以及您使用的数据库。

    如果它不起作用,您可以尝试最新版本,或记录错误。

    【讨论】:

      【解决方案2】:

      预计第一个查询不起作用。 IN 表达式中条件运算符的左侧不能是实体。可以使用的是枚举、字符串、数字和日期类型。右侧的允许值确实取决于左侧的内容。在 JPA 2.0 规范中,这被告知如下:

      in_expression::=   
          {state_field_path_expression | type_discriminator} **[NOT] IN**  
              { ( in_item {, in_item}* ) | (subquery) 
                 |collection_valued_input_parameter }   
      in_item ::= literal | single_valued_input_parameter   
      

      state_field_path_expression 必须具有字符串、数字、日期、时间、时间戳或枚举值。

      文字和/或输入参数值必须像同一个抽象 state_field_path_expression in 类型的模式类型。

      【讨论】:

      • 但第一个查询适用于 JPA 2.1 和 Glassfish 4.0。所以我认为第二个也应该起作用。
      • 由于上述原因,第一个和第二个查询(比较使用实体的查询)在规范方面都是无效的。 JPA 2.1 也没有改变。如果某些东西有效,那只是因为供应商决定(或纯粹是意外实现)方便的扩展。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-07-30
      • 2013-12-03
      • 2020-07-07
      • 2022-11-26
      • 2021-12-17
      • 2018-05-11
      • 2020-07-03
      相关资源
      最近更新 更多