【问题标题】:JPA CriterialBuilder.concat force to use concat functionJPA CriterialBuilder.concat 强制使用 concat 函数
【发布时间】:2014-10-17 15:44:44
【问题描述】:

我正在使用CriteriaBuilder.concat 连接 2 个字符串,使用以下代码:

Expression<String> concat = criteriaBuilder.concat(expr1, expr2)

但是生成的 SQL 是这样的:

select distinct col_1 || col_2

导致org.hibernate.hql.ast.QuerySyntaxException:

expecting CLOSE, found '||' near line 1, column 48 [
select count(distinct generatedAlias0.hostname || generatedAlias0.device) from ...
                                                ^(1,48)

我想知道如何强制它生成以下使用concat() 函数而不是|| 运算符的SQL?

select distinct concat(col_1, col_2)

更新:

从错误中我们可以看出问题更多在 Hibernate (v3.6.10.Final) 方面,这就是为什么让 MySQL 接受|| 进行连接没有帮助,更新到新版本也不是我的选择。

谢谢

【问题讨论】:

标签: java hibernate jpa concat


【解决方案1】:

我也有这个问题。 JPA/HQL 生成的 sql 查询使用pipes as concat(即||)。

  • 我正在使用 Mariadb 10,Springboot-data-jpa2.0.6(带有 Hibernate 5.2.17)

问题示例

  • 给定 HQL:select x from Xxx x where concat(x.field1, x.field2) = $1
  • 生成的 SQL:select ..... where (x.field1 || x.field2) = ?

原因:

解决方法:

  1. (首选)ranther然后使用concat函数,有一个类似的concat_wshttps://mariadb.com/kb/en/concat_ws/
  2. 使用 JPA 原生查询@Query(nativeQuery = true, value ="select * from ....")
  3. set global sql_mode=&lt;list of modes which contains PIPES_AS_CONCAT&gt; (我没试过)

【讨论】:

  • 使用原生查询确实是一个可行的解决方案,谢谢!
【解决方案2】:

我对 concat 函数也有类似的问题。 我在 selectCase 中使用了 concat 函数,这也返回了相同的 QuerySyntaxException。

我的解决方法是通过标准构建器函数使用 concat 函数:

cb().selectCase().when(cb().equal(root.get(Person_.flag), cb().literal("1")), 
        cb().function("CONCAT", String.class, root.get(Person_.something), cb().literal(" bla bla bla")))
    .otherwise(root.get(Person_.something))) 

休眠版本 4.3.11.Final

【讨论】:

    【解决方案3】:

    我实际上找到了一种解决方法。通过使用 @Formula(来自 Hibernate)而不是 CriteriaBuilder 来完成相同的任务,如下所示:

    @Entity
    public class MyEntity {
    
      @Column(name="col_a")
      private String colA;
    
      @Column(name="col_b")
      private String colB;
    
      @Formula("concat(col_a, col_b)")
      private String concated;
    
      //...
    }
    

    这样我可以将concated 字段用于CriteriaBuilder.countDistinct

    //...
    
    Expression<?> exp = criteriaBuilder.countDistinct(entity.get("concated"));
    criteriaQuery.select(exp);
    
    TypedQuery<Long> query = entityManager.createQuery(criteriaQuery);
    return query.getSingleResult();
    

    我希望 JPA 能够(或希望已经)支持具有多个列的 countDistinct,然后可以避免所有这些混乱(参见:How to countDistinct on multiple columns,答案是 NO)。 p>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-07-31
      • 1970-01-01
      • 1970-01-01
      • 2018-06-06
      • 1970-01-01
      • 1970-01-01
      • 2015-02-26
      相关资源
      最近更新 更多