OpenJPA 2.0 supports count(*) or not?
-------------------------------------
Key: OPENJPA-1781
URL: https://issues.apache.org/jira/browse/OPENJPA-1781
Project: OpenJPA
Issue Type: Bug
Components: query
Affects Versions: 2.0.0
Environment: JDK 1.6, OpenJPA 2.0, Shindig 2.0
Reporter: Kai Feng Zhang
Priority: Critical
Today I encountered a jpql parse exception thrown from openjpa 2.0. I searched
here and found some links talking about count(*), but seems 2.0 still has such
issue.
https://issues.apache.org/jira/browse/OPENJPA-566
https://issues.apache.org/jira/browse/OPENJPA-1440
My select statement is: "select count(*) from PersonDb p where p.objectId in
(select f.friend.objectId from PersonDb p, FriendDb f where p.objectId =
f.person.objectId and p.id in (?1)) ".
Please note that the count(*) in it is added by openjpa code itself, in
JPQLUtil.java, there is a hardcoded "count(*)" in this method:
public static Long getTotalResults(EntityManager entityManager, String query,
List<?> parametersValues) {
int fromIndex = 0;
String queryInUpperCase = query.toUpperCase();
// If JPA query starts with FROM then fromIndex as 0 is correct,
// otherwise find where FROM keyword starts in the query string and set the
fromIndex.
if (!queryInUpperCase.startsWith("FROM ")) {
fromIndex = queryInUpperCase.indexOf(" FROM ");
if (fromIndex == -1) {
// Couldn't find the FROM keyword in the query
throw new
ProtocolException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Invalid query
[" + query + ']');
}
}
query = "select count(*) " + query.substring(fromIndex, query.length());
Query q = createQuery(entityManager, query, parametersValues);
return (Long) q.getSingleResult();
}
But in JPQLParser.java, it will parse this jpql, and then throw exception:
public Object parse(String ql, ExpressionStoreQuery query) {
if (query.getContext().getParameterDeclaration() != null)
throw new UserException(_loc.get("param-decs-invalid"));
try {
return new JPQLExpressionBuilder.ParsedJPQL(ql);
} catch (ParseException e) {
throw new ParseException(_loc.get("jpql-parse-error",
ql, e.getMessage()).getMessage(), e);
}
}
Exception stack is here:
<openjpa-2.0.0-r422266:935683 nonfatal user error>
org.apache.openjpa.persistence.ArgumentException: "Encountered "count ( *" at
character 8, but expected: ["(", "+", "-", ":", "?", "ABS", "AVG", "CASE",
"COALESCE", "CONCAT", "COUNT", "CURRENT_DATE", "CURRENT_TIME",
"CURRENT_TIMESTAMP", "DISTINCT", "ENTRY", "INDEX", "KEY", "LENGTH", "LOCATE",
"LOWER", "MAX", "MIN", "MOD", "NEW", "NULLIF", "OBJECT", "SIZE", "SQRT",
"SUBSTRING", "SUM", "TRIM", "TYPE", "UPPER", "VALUE", <BOOLEAN_LITERAL>,
<DATE_LITERAL>, <DECIMAL_LITERAL>, <IDENTIFIER>, <INTEGER_LITERAL>,
<STRING_LITERAL>, <TIMESTAMP_LITERAL>, <TIME_LITERAL>]." while parsing JPQL
"select count(*) from PersonDb p where p.objectId in (select f.friend.objectId
from PersonDb p, FriendDb f where p.objectId = f.person.objectId and p.id in
(?1))". See nested stack trace for original parse error.
at org.apache.openjpa.kernel.jpql.JPQLParser.parse(JPQLParser.java:51)
at
org.apache.openjpa.kernel.ExpressionStoreQuery.newCompilation(ExpressionStoreQuery.java:150)
at
org.apache.openjpa.kernel.QueryImpl.newCompilation(QueryImpl.java:670)
at
org.apache.openjpa.kernel.QueryImpl.compilationFromCache(QueryImpl.java:652)
at
org.apache.openjpa.kernel.QueryImpl.compileForCompilation(QueryImpl.java:618)
at
org.apache.openjpa.kernel.QueryImpl.compileForExecutor(QueryImpl.java:680)
at org.apache.openjpa.kernel.QueryImpl.compile(QueryImpl.java:587)
at
org.apache.openjpa.persistence.EntityManagerImpl.createQuery(EntityManagerImpl.java:985)
at
org.apache.openjpa.persistence.EntityManagerImpl.createQuery(EntityManagerImpl.java:971)
at
org.apache.openjpa.persistence.EntityManagerImpl.createQuery(EntityManagerImpl.java:100)
at
org.apache.shindig.social.opensocial.jpa.spi.JPQLUtils.createQuery(JPQLUtils.java:112)
at
org.apache.shindig.social.opensocial.jpa.spi.JPQLUtils.getTotalResults(JPQLUtils.java:98)
at
org.apache.shindig.social.opensocial.jpa.spi.PersonServiceDb.getPeople(PersonServiceDb.java:135)
at
org.apache.shindig.social.opensocial.service.PersonHandler.get(PersonHandler.java:86)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at
org.apache.shindig.protocol.DefaultHandlerRegistry$MethodCaller.call(DefaultHandlerRegistry.java:483)
at
org.apache.shindig.protocol.DefaultHandlerRegistry$RpcInvocationHandler.execute(DefaultHandlerRegistry.java:301)
at
org.apache.shindig.protocol.DefaultHandlerRegistry$RpcInvocationWrapper.execute(DefaultHandlerRegistry.java:325)
at
org.apache.shindig.protocol.JsonRpcServlet.dispatchBatch(JsonRpcServlet.java:185)
at
org.apache.shindig.protocol.JsonRpcServlet.service(JsonRpcServlet.java:130)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at
org.apache.shindig.auth.AuthenticationServletFilter.callChain(AuthenticationServletFilter.java:125)
at
org.apache.shindig.auth.AuthenticationServletFilter.doFilter(AuthenticationServletFilter.java:88)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
at
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
at
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
at
org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:619)
Caused by: <openjpa-2.0.0-r422266:935683 nonfatal user error>
org.apache.openjpa.persistence.ArgumentException: Encountered "count ( *" at
character 8, but expected: ["(", "+", "-", ":", "?", "ABS", "AVG", "CASE",
"COALESCE", "CONCAT", "COUNT", "CURRENT_DATE", "CURRENT_TIME",
"CURRENT_TIMESTAMP", "DISTINCT", "ENTRY", "INDEX", "KEY", "LENGTH", "LOCATE",
"LOWER", "MAX", "MIN", "MOD", "NEW", "NULLIF", "OBJECT", "SIZE", "SQRT",
"SUBSTRING", "SUM", "TRIM", "TYPE", "UPPER", "VALUE", <BOOLEAN_LITERAL>,
<DATE_LITERAL>, <DECIMAL_LITERAL>, <IDENTIFIER>, <INTEGER_LITERAL>,
<STRING_LITERAL>, <TIMESTAMP_LITERAL>, <TIME_LITERAL>].
at
org.apache.openjpa.kernel.jpql.JPQL.generateParseException(JPQL.java:13087)
at org.apache.openjpa.kernel.jpql.JPQL.jj_consume_token(JPQL.java:12961)
at org.apache.openjpa.kernel.jpql.JPQL.select_expression(JPQL.java:1001)
at org.apache.openjpa.kernel.jpql.JPQL.select_expressions(JPQL.java:930)
at org.apache.openjpa.kernel.jpql.JPQL.select_clause(JPQL.java:865)
at org.apache.openjpa.kernel.jpql.JPQL.select_statement(JPQL.java:87)
at org.apache.openjpa.kernel.jpql.JPQL.parseQuery(JPQL.java:63)
at
org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder$ParsedJPQL.parse(JPQLExpressionBuilder.java:2371)
at
org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder$ParsedJPQL.<init>(JPQLExpressionBuilder.java:2358)
at org.apache.openjpa.kernel.jpql.JPQLParser.parse(JPQLParser.java:49)
... 39 more
Can you please tell me if openjpa support count(*) or not, or if not then will
fix the method in JPQLUtil.java?
Thank you.
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.