【问题标题】:JPA - Syntax error parsing SELECT GREATEST(c.field, mc.field), LEAST(c.field, mc.field) FROM tableJPA - 语法错误解析 SELECT GREATEST(c.field, mc.field), LEAST(c.field, mc.field) FROM table
【发布时间】:2016-07-28 17:22:43
【问题描述】:

我需要获得两个字段之间的最大值和最小值。我将 JPA 2.1 与 EclipsLink 一起使用。

这是我的简化查询:

SELECT GREATEST(c.min, mc.max), LEAST(c.max, mc.max) 
FROM
   MethodCategory mc, OperationMethod om, Client c 
       JOIN
   User u ON c.id = u.client.id
WHERE
   om.method = 1
   AND om.method.category = "SUPER"
   AND om.isDeleted = false 
   AND om.user = u
   AND u.id <> 1 
   AND c.isOnline = TRUE 
   AND c.isActive = TRUE;

它在 MySQL Workbench 上运行良好,作为原始 sql 查询,但是当我将此查询复制到我的 entityManager.createQuery(query) 时,我得到一个异常。

以下是我将查询复制到 JPA 的方式:

TypedQuery<Object[]> query = em.createQuery("SELECT GREATEST(c.min, mc.min), LEAST(c.max, mc.max) "
                + " FROM\n"
                + "    MethodCategory mc, OperationMethod om, Client c \n"
                + "        JOIN\n"
                + "    User u ON c.id = u.client.id \n"
                + " WHERE\n"
                + "    om.method = :method \n"
                + "    AND om.method.category = :categoryName \n"
                + "    AND om.isDeleted = false \n"
                + "    AND om.user = u \n"
                + "    AND u.id <> :userId \n" 
                + "    AND c.isOnline = TRUE \n"
                + "    AND c.isActive = TRUE \n",
                Object[].class);

每当我执行这个 JPQL 查询时,我都会得到这个异常:

Exception Description: Syntax error parsing [SELECT GREATEST(c.min, mc.min), LEAST(c.max, mc.max)  FROM (...)
[14, 15] The SELECT clause has 'GREATEST' and '(c.min, mc.min)' that are not separated by a comma.
[72, 73] The SELECT clause has 'LEAST' and '(c.max, mc.max)' that are not separated by a comma.

这个例外对我来说真的没有意义。我清楚地用逗号分隔 GREATEST() 和 LEAST() 和 GREATEST , (value) 没有任何意义。

我在这里做错了什么?

【问题讨论】:

  • 我的建议是查看SO Question 的同一主题,该主题详细介绍了使用 CriteriaBuilder 来实现您所寻找的目标。
  • @JustinKyleParton 谢谢。那将是我最坏的情况解决方案。我目前正在尝试避免将此查询重写为 CriteriaBuilder。
  • 我没有用过这个,所以我不会把它作为答案,但是去这个页面EclipseLink Special Operators 并尝试使用它来实现你想要的。还要看看它下面的运算符

标签: java mysql jpa eclipselink


【解决方案1】:

JPA 2.0 不支持聚合函数 greatestleastsyntax 中没有提到它们。您是否尝试过 minmax 代替:max(c.min,mc.min), min(c.max,mc.max)

【讨论】:

    【解决方案2】:

    另一个选项可能是为 MySQL 增加 JPA 数据库方言。我不熟悉 EclipseLink 但使用 Hibernate 会是这样的:

    import org.hibernate.dialect.MySQL5InnoDBDialect;
    import org.hibernate.dialect.function.StandardSQLFunction;
    
    public class CustomMySQL5InnoDBDialect extends MySQL5InnoDBDialect {
        public CustomMySQL5InnoDBDialect() {
            super();
    
            registerFunction("greatest", new StandardSQLFunction("greatest", null));
            registerFunction("least", new StandardSQLFunction("least", null));
        }
    }
    

    【讨论】:

    • 我没有尝试这个,因为我解决了我的问题,我没有时间重构/尝试这种方法,但这似乎是一个有趣的解决方案。 +1
    【解决方案3】:

    我最终得到了以下解决方案,MIN/MAXCASE THEN 的混合

    这是查询:

    SELECT  
    MIN(CASE WHEN (c.min < mc.min) THEN mc.min ELSE c.min END) as min, 
    MAX(CASE WHEN (c.max < mc.max) THEN c.max ELSE mc.max END) as max  
    FROM ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-14
      • 2013-12-17
      • 1970-01-01
      • 2012-08-22
      • 1970-01-01
      • 1970-01-01
      • 2011-04-17
      • 2014-12-28
      相关资源
      最近更新 更多