-
Notifications
You must be signed in to change notification settings - Fork 63
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for "SELECT ... AS identifier1, ... AS identifier2" in JPQL constructor expressions (to be used by WHERE and/or ORDER BY clauses) #297
Comments
Hi
The query does not need the alias, as the JPA will populate the attribute
according to the constructor. Remove the ' AS {attribute}' of the query.
Look at the example below:
SUM(CASE WHEN gl.hasPlayed = FALSE THEN 1 ELSE 0 END) AS
gamesplayed, // <-- REMOVE AS gamesplayed"
SUM(CASE WHEN gl.starter = TRUE THEN 1 ELSE 0 END) AS
gamesstarted, // <-- REMOVE AS gamesstarted"
Best Regards,
Rhuan Rocha
Em seg., 16 de nov. de 2020 às 14:57, Kawu <[email protected]>
escreveu:
… I'm trying to use JPQL SELECT NEW org.mydomain.WhatEverDto( SELECT
my.expr1 AS identifier, my.expr2 AS identifier, ... ) syntax, that is SELECT
... AS in a constructor expression:
<named-query name="GameLog.findPlayerStatDtos">
<query>
SELECT NEW net.bbstats.dto.PlayerStatDto(
gl.playerId,
gl.seasonStartYear,
gl.lastName,
gl.firstName,
gl.incognito,
COUNT(DISTINCT gl.gameId) AS games, <--
SUM(CASE WHEN gl.hasPlayed = FALSE THEN 1 ELSE 0 END) AS gamesplayed, <--
SUM(CASE WHEN gl.starter = TRUE THEN 1 ELSE 0 END) AS gamesstarted, <--
SUM(gl.threePointersMade),
SUM(gl.freeThrowsMade),
SUM(gl.freeThrowsAttempted),
SUM(gl.personalFouls),
SUM(CASE WHEN gl.personalFouls >= 5 THEN 1 ELSE 0 END),
SUM(gl.points) AS points, <--
MAX(gl.points),
MIN(gl.points)
)
FROM GameLog gl
WHERE gl.roundId = :roundId AND gl.groupCode = :groupCode AND gl.rosterId IN :rosterIds
GROUP BY
gl.playerId,
gl.seasonStartYear,
gl.lastName,
gl.firstName,
gl.incognito
ORDER BY gamesstarted DESC, <-- referenced here
games DESC, <-- referenced here
points DESC, <-- referenced here
gl.lastName,
gl.firstName
</query>
</named-query>
A complete example is on SO here:
https://stackoverflow.com/questions/59677453/eclipselink-throws-jpqlexception-on-using-select-as-in-a-constructor-express
The purpose is to select a column for the constructor expression AND be
able to sort the resulting elements/DTOs via the ORDER BY clause without
having to repeat the (possibly complex) expression there.
Placing an "AS identifier" after the constructor item *already works in
Hibernate*, but *fails with an exception in EclipseLink*:
at org.eclipse.persistence.exceptions.EntityManagerSetupException.deployFailed(EntityManagerSetupException.java:241)
... 184 more
Caused by: Exception [EclipseLink-0] (Eclipse Persistence Services - 2.7.5.v20191016-ea124dd158): org.eclipse.persistence.exceptions.JPQLException
Exception Description: Syntax error parsing [
SELECT NEW net.bbstats.dto.PlayerStatDto(
gl.playerId,
gl.seasonStartYear,
gl.lastName,
gl.firstName,
gl.incognito,
COUNT(DISTINCT gl.gameId) AS games,
SUM(CASE WHEN gl.hasPlayed = FALSE THEN 1 ELSE 0 END) AS gamesplayed,
SUM(CASE WHEN gl.starter = TRUE THEN 1 ELSE 0 END) AS gamesstarted,
SUM(gl.threePointersMade),
SUM(gl.freeThrowsMade),
SUM(gl.freeThrowsAttempted),
SUM(gl.personalFouls),
SUM(CASE WHEN gl.personalFouls >= 5 THEN 1 ELSE 0 END),
SUM(gl.points) AS points,
MAX(gl.points),
MIN(gl.points)
)
FROM GameLog gl
WHERE gl.roundId = :roundId AND gl.groupCode = :groupCode AND gl.rosterId IN :rosterIds
GROUP BY
gl.playerId,
gl.seasonStartYear,
gl.lastName,
gl.firstName,
gl.incognito
ORDER BY gamesstarted DESC, gamesplayed DESC, games DESC, points DESC, gl.lastName, gl.firstName
].
[140, 141] The constructor expression has two constructor items ('COUNT(DISTINCT gl.gameId)' and 'AS games') that are not separated by a comma.
[204, 205] The constructor expression has two constructor items ('SUM(CASE WHEN gl.hasPlayed = FALSE THEN 1 ELSE 0 END)' and 'AS gamesplayed') that are not separated by a comma.
[271, 272] The constructor expression has two constructor items ('SUM(CASE WHEN gl.starter = TRUE THEN 1 ELSE 0 END)' and 'AS gamesstarted') that are not separated by a comma.
[462, 463] The constructor expression has two constructor items ('SUM(gl.points)' and 'AS points') that are not separated by a comma.
[141, 149] The expression is invalid, which means it does not follow the JPQL grammar.
[205, 219] The expression is invalid, which means it does not follow the JPQL grammar.
[272, 287] The expression is invalid, which means it does not follow the JPQL grammar.
[463, 472] The expression is invalid, which means it does not follow the JPQL grammar.
at org.eclipse.persistence.internal.jpa.jpql.HermesParser.buildException(HermesParser.java:157)
at org.eclipse.persistence.internal.jpa.jpql.HermesParser.validate(HermesParser.java:336)
at org.eclipse.persistence.internal.jpa.jpql.HermesParser.populateQueryImp(HermesParser.java:280)
at org.eclipse.persistence.internal.jpa.jpql.HermesParser.buildQuery(HermesParser.java:165)
at org.eclipse.persistence.internal.jpa.EJBQueryImpl.buildEJBQLDatabaseQuery(EJBQueryImpl.java:142)
at org.eclipse.persistence.internal.jpa.JPAQuery.processJPQLQuery(JPAQuery.java:225)
at org.eclipse.persistence.internal.jpa.JPAQuery.prepare(JPAQuery.java:186)
at org.eclipse.persistence.queries.DatabaseQuery.prepareInternal(DatabaseQuery.java:631)
at org.eclipse.persistence.internal.sessions.AbstractSession.processJPAQuery(AbstractSession.java:4502)
at org.eclipse.persistence.internal.sessions.AbstractSession.processJPAQueries(AbstractSession.java:4462)
at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.initializeDescriptors(DatabaseSessionImpl.java:645)
at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.postConnectDatasource(DatabaseSessionImpl.java:868)
at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.loginAndDetectDatasource(DatabaseSessionImpl.java:811)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.login(EntityManagerFactoryProvider.java:256)
at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:772)
... 182 more
BNF from the JPA 2.2 spec (see answer on SO):
constructor_item ::=
single_valued_path_expression |
scalar_expression |
aggregate_expression |
identification_variable
aggregate_expression ::=
{ AVG | MAX | MIN | SUM} ([DISTINCT] state_valued_path_expression) |
COUNT ([DISTINCT] identification_variable | state_valued_path_expression
|single_valued_object_path_expression) |
function_invocation
The BNF clearly states, that a constructor_item cannot have an optional
[AS] result_variable/identifier.
This feature might change the BNF to:
constructor_item ::=
{single_valued_path_expression |
scalar_expression |
aggregate_expression |
identification_variable} [AS] result_variable <-- ?
aggregate_expression ::=
{ AVG | MAX | MIN | SUM} ([DISTINCT] state_valued_path_expression) |
COUNT ([DISTINCT] identification_variable | state_valued_path_expression
|single_valued_object_path_expression) |
function_invocation
Let me know what you think. 💡
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#297>, or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACN424BYIDV5BYZPCNSQHJTSQFRXBANCNFSM4TXPTQCA>
.
|
Did you notice the
|
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I'm trying to use JPQL
SELECT NEW org.mydomain.WhatEverDto( SELECT my.expr1 AS identifier, my.expr2 AS identifier, ... )
syntax, that isSELECT ... AS
in a constructor expression to later be used in anORDER BY
clause:A complete example is on SO here:
https://stackoverflow.com/questions/59677453/eclipselink-throws-jpqlexception-on-using-select-as-in-a-constructor-express
The purpose is to select a column for the constructor expression AND be able to sort the resulting elements/DTOs via the ORDER BY clause without having to repeat the (possibly complex) expression there.
Placing an "AS identifier" after the constructor item already works in Hibernate, but fails with an exception in EclipseLink:
BNF from the JPA 2.2 spec (see answer on SO):
The BNF clearly states, that a constructor_item cannot have an optional [AS] result_variable/identifier.
This feature might change the BNF to:
Should be extended to
WHERE
and other clauses if applicable.Let me know what you think. 💡
The text was updated successfully, but these errors were encountered: