【发布时间】:2014-08-02 23:22:29
【问题描述】:
我很难弄清楚如何将以下 SQL 转换为 JPQL
SELECT * FROM consorder
WHERE
consorder.redistid LIKE '123%'
HAVING
MAX(consorder.redistid)
(在 MySQL 下就像一个魅力)。
@Query("select c from ConsignmentOrder c" +
" where c.redistributionId like ?1" +
" having max(c.redistributionId)")
我得到以下异常:
Caused by: <openjpa-2.2.2-r422266:1468616 nonfatal user error> org.apache.openjpa.persistence.ArgumentException: Encountered "max ( c . redistributionId ) <EOF>" at character 79, but expected: ["(", ")", "*", "+", "-", ".", "/", ":", "<", "<=", "<>", "=", ">", ">=", "?", "ABS", "ALL", "AND", "ANY", "AS", "ASC", "AVG", "BETWEEN", "BOTH", "BY", "CASE", "COALESCE", "CONCAT", "COUNT", "CURRENT_DATE", "CURRENT_TIME", "CURRENT_TIMESTAMP", "DELETE", "DESC", "DISTINCT", "EMPTY", "ESCAPE", "EXISTS", "FETCH", "FROM", "GROUP", "HAVING", "IN", "INDEX", "INNER", "IS", "JOIN", "KEY", "LEADING", "LEFT", "LENGTH", "LIKE", "LOCATE", "LOWER", "MAX", "MEMBER", "MIN", "MOD", "NEW", "NOT", "NULL", "NULLIF", "OBJECT", "OF", "OR", "ORDER", "OUTER", "SELECT", "SET", "SIZE", "SOME", "SQRT", "SUBSTRING", "SUM", "TRAILING", "TRIM", "TYPE", "UPDATE", "UPPER", "VALUE", "WHERE", <BOOLEAN_LITERAL>, <DATE_LITERAL>, < DECIMAL_LITERAL>, <IDENTIFIER>, <INTEGER_LITERAL>, <STRING_LITERAL2>, <STRING_LITERAL>, <TIMESTAMP_LITERAL>, <TIME_LITERAL>].
at org.apache.openjpa.kernel.jpql.JPQL.generateParseException(JPQL.java:13162)
at org.apache.openjpa.kernel.jpql.JPQL.jj_consume_token(JPQL.java:13036)
at org.apache.openjpa.kernel.jpql.JPQL.conditional_primary(JPQL.java:1980)
at org.apache.openjpa.kernel.jpql.JPQL.conditional_factor(JPQL.java:1958)
at org.apache.openjpa.kernel.jpql.JPQL.conditional_term(JPQL.java:1807)
at org.apache.openjpa.kernel.jpql.JPQL.conditional_expression(JPQL.java:1769)
at org.apache.openjpa.kernel.jpql.JPQL.having_clause(JPQL.java:1701)
at org.apache.openjpa.kernel.jpql.JPQL.select_statement(JPQL.java:107)
at org.apache.openjpa.kernel.jpql.JPQL.parseQuery(JPQL.java:63)
at org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder$ParsedJPQL.parse(JPQLExpressionBuilder.java:2401)
at org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder$ParsedJPQL.<init>(JPQLExpressionBuilder.java:2388)
at org.apache.openjpa.kernel.jpql.JPQLParser.parse(JPQLParser.java:49)
... 96 moreEncountered "max ( c . redistributionId ) <EOF>" at character 79, but expected: ["(", ")", "*",
任何帮助将不胜感激。
编辑: 我稍微重组了查询:
@Query("select c from ConsignmentOrder c where c.redistributionId = (select max(co.redistributionId) from (select co ConsignmentOrder co where co.redistributionId like ?1) as tmp )")
现在异常类似:
Caused by: <openjpa-2.2.2-r422266:1468616 nonfatal user error> org.apache.openjpa.persistence.ArgumentException: Encountered "c . redistributionId = ( select max ( co . redistributionId ) from (" at character 40, but expected: ["(", ")", "*", "+", ",", "-", ".", "/", ":", "<", "<=", "<>", "=", ">", ">=", "?", "ABS", "ALL", "AND", "ANY", "AS", "ASC", "AVG", "BETWEEN", "BOTH", "BY", "CASE", "CLASS", "COALESCE", "CONCAT", "COUNT", "CURRENT_DATE", "CURRENT_TIME", "CURRENT_TIMESTAMP", "DELETE", "DESC", "DISTINCT", "ELSE", "EMPTY", "END", "ENTRY", "ESCAPE", "EXISTS", "FETCH", "FROM", "GROUP", "HAVING", "IN", "INDEX", "INNER", "IS", "JOIN", "KEY", "LEADING", "LEFT", "LENGTH", "LIKE", "LOCATE", "LOWER", "MAX", "MEMBER", "MIN", "MOD", "NEW", "NOT", "NULL", "NULLIF", "OBJECT", "OF", "OR", "ORDER", "OUTER", "SELECT", "SET", "SIZE", "SOME", "SQRT", "SUBSTRING", "SUM", "THEN", "TRAILING", "TRIM", "TYPE", "UPDATE", "UPPER", "VALUE", "WHEN", "WHERE", <BOOLEAN_LITERAL>, <DATE_LITERAL>, <DECIMAL_LITERAL>, <IDENTIFIER>, <INTEGER_LITERAL>, <STRING_LITERAL2>, <STRING_LITERAL>, <TIMESTAMP_LITERAL>, <TIME_LITERAL>].
没有误导性的EOF。
【问题讨论】:
-
我猜是编码错误,因为您的错误中出现了文件结尾字符
-
嗯。我觉得这很奇怪,因为我的 IDE 既没有显示字符,也没有出现在这里 - 但我从我的 IDE 复制并粘贴了它......我看到了 EOF,但认为它是无稽之谈并忽略了它。
-
我建议将您的查询稍微配对一下,看看
是您的环境中的问题,还是 OpenJPA 的问题。 -
我认为,我可以排除环境问题:1)我使用纯文本编辑器编辑文件 2)语义等效查询引发相同的异常。我认为,MySQL 的行为方式很肮脏。我怀疑,我不能像 MySQL 允许的那样在 OpenJPA 中使用聚合。我的解决方案现在是完整的 Java:retrieve all and find max.完成。
-
HAVING MAX(consorder.redistid) ...什么?您不仅有一个隐含的 GROUP BY,它没有列,也没有包含在 select 下的聚合函数;您没有指定完整的条件。这肯定是 MySQL 可以容忍但不应该使用的“脏 sql”。