Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 325400

Summary: Query keys are are still not well supported in JPQL (and native) queries
Product: z_Archived Reporter: Frank Schwarz <fs5>
Component: EclipselinkAssignee: Nobody - feel free to take it <nobody>
Status: CLOSED FIXED QA Contact:
Severity: major    
Priority: P3 CC: eclipselink.orm-inbox, michael.braeuer, michael.f.obrien, tom.ware
Version: unspecified   
Target Milestone: ---   
Hardware: All   
OS: All   
Whiteboard:
Attachments:
Description Flags
testcase
none
Proposed fix none

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