Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 325400 - Query keys are are still not well supported in JPQL (and native) queries
Summary: Query keys are are still not well supported in JPQL (and native) queries
Status: CLOSED FIXED
Alias: None
Product: z_Archived
Classification: Eclipse Foundation
Component: Eclipselink (show other bugs)
Version: unspecified   Edit
Hardware: All All
: P3 major (vote)
Target Milestone: ---   Edit
Assignee: Nobody - feel free to take it CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-09-15 18:04 EDT by Frank Schwarz CLA
Modified: 2022-06-09 10:22 EDT (History)
4 users (show)

See Also:


Attachments
testcase (5.79 KB, application/x-zip)
2010-09-15 18:08 EDT, Frank Schwarz CLA
no flags Details
Proposed fix (10.23 KB, patch)
2010-09-22 15:11 EDT, Tom Ware CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Frank Schwarz CLA 2010-09-15 18:04:28 EDT
Build Identifier: Trunk, r8200 (2010/09/15)

EclipseLink 2.1.0 was advertised to support query-keys in JPQL queries. This support is unfortunately still rather limited.


* select p, count(c) from Parent p left join p.noFlagChildren c group by p
noFlagChildren is a OneToManyQueryKey.

Exception:
Local Exception Stack: 
Exception [EclipseLink-6070] (Eclipse Persistence Services - @VERSION@.@QUALIFIER@): org.eclipse.persistence.exceptions.QueryException
Exception Description: Invalid use of a query key [OneToManyQueryKey(noFlagChildren)] representing a "to-many" relationship in an expression.  Use anyOf() rather than get().
	at org.eclipse.persistence.exceptions.QueryException.invalidUseOfToManyQueryKeyInExpression(QueryException.java:735)
	at org.eclipse.persistence.internal.expressions.QueryKeyExpression.validateNode(QueryKeyExpression.java:887)
	at org.eclipse.persistence.expressions.Expression.normalize(Expression.java:3009)
	at org.eclipse.persistence.internal.expressions.DataExpression.normalize(DataExpression.java:342)
	at org.eclipse.persistence.internal.expressions.QueryKeyExpression.normalize(QueryKeyExpression.java:612)
	at org.eclipse.persistence.internal.expressions.QueryKeyExpression.normalize(QueryKeyExpression.java:599)
	at org.eclipse.persistence.internal.expressions.FunctionExpression.normalize(FunctionExpression.java:385)
	at org.eclipse.persistence.internal.expressions.SQLSelectStatement.normalize(SQLSelectStatement.java:1311)
	at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.buildReportQuerySelectStatement(ExpressionQueryMechanism.java:563)
	at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.buildReportQuerySelectStatement(ExpressionQueryMechanism.java:509)
	at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.prepareReportQuerySelectAllRows(ExpressionQueryMechanism.java:1545)
	at org.eclipse.persistence.queries.ReportQuery.prepareSelectAllRows(ReportQuery.java:1298)
	at org.eclipse.persistence.queries.ReadAllQuery.prepare(ReadAllQuery.java:628)
	at org.eclipse.persistence.queries.ReportQuery.prepare(ReportQuery.java:1047)
	at org.eclipse.persistence.queries.DatabaseQuery.checkPrepare(DatabaseQuery.java:541)
	at org.eclipse.persistence.queries.ObjectLevelReadQuery.checkPrepare(ObjectLevelReadQuery.java:822)
	at org.eclipse.persistence.queries.DatabaseQuery.prepareCall(DatabaseQuery.java:1617)
	at org.eclipse.persistence.internal.jpa.EJBQueryImpl.buildEJBQLDatabaseQuery(EJBQueryImpl.java:266)
	at org.eclipse.persistence.internal.jpa.EJBQueryImpl.buildEJBQLDatabaseQuery(EJBQueryImpl.java:182)
	at org.eclipse.persistence.internal.jpa.EJBQueryImpl.<init>(EJBQueryImpl.java:134)
	at org.eclipse.persistence.internal.jpa.EJBQueryImpl.<init>(EJBQueryImpl.java:118)
	at org.eclipse.persistence.internal.jpa.EntityManagerImpl.createQuery(EntityManagerImpl.java:1374)
	at org.eclipse.persistence.internal.jpa.EntityManagerImpl.createQuery(EntityManagerImpl.java:1396)
	at OnClauseTest.queryKeyJPQL(OnClauseTest.java:86)


Even native report queries are sometimes at odds with query-keys.

* report query: query.addCount("item-count", expr.anyOfAllowingNone("noFlagChildren"))
noFlagChildren is a OneToManyQueryKey.

This one fails with an invalid SQL statement: SELECT T0.ID, -->COUNT()<-- FROM PARENT T0 ...
This same with a proper field (query.addCount("item-count", expr.anyOfAllowingNone("children"))) will work though!
You have to apply this workaround: query.addCount("item-count", expr.anyOfAllowingNone("noFlagChildren").get("id"))

Reproducible: Always

Steps to Reproduce:
A junit test will be provided shortly.
Comment 1 Frank Schwarz CLA 2010-09-15 18:08:07 EDT
Created attachment 178986 [details]
testcase

JUnit Testcase
Comment 2 Tom Ware CLA 2010-09-22 15:11:23 EDT
Created attachment 179401 [details]
Proposed fix
Comment 3 Tom Ware CLA 2010-09-23 11:30:19 EDT
Fix checked into trunk stream.

This fix does two things.

1. It allows our JPQL parser to calculate that a relationship defined by a query key is a plural relationship
2. It fixes our count implementation to deal with xToMany query keys better

Reviewed by Chris Delahunt

Added to test to JUnitJPQLComplexTestSuite
Comment 4 Eclipse Webmaster CLA 2022-06-09 10:22:13 EDT
The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink