I defined multiple JPA named queries this way:
SELECT group FROM FOO_Group group WHERE group.valid = :valid ORDER BY group.date
Even though group
is a reserved keyword in SQL, this never seemed to bother Hibernate.
Now, however, I had to define a named query that joins two tables:
SELECT group FROM FOO_User user JOIN user.group group WHERE group.valid = :valid ORDER BY group.date
This time the query fails and Hibernate states that BY
was expected (as in GROUP BY
), but WHERE
was found.
I know that using reserved keywords as column, table or entity names is generally a bad idea. But I wonder, why it did not cause any trouble in my old queries, but now fails in the joining query. Is there any syntax that allows me to use group
in the new query as well? I tried JOIN user.group AS group
, but that did not work out as expected.
Right now, all I can do is renaming the identifier:
SELECT g FROM FOO_User user JOIN user.group g WHERE g.valid = :valid ORDER BY g.date
You should distinguish SQL key words and JPQL/HQL reserved identifiers.
You can use SQL quoted identifiers for column/table names.
But according to the JPA specification (see section 4.4.1 Identifiers)
Reserved identifiers must not be used as identification variables or result variables (see section 4.8).
Your first query worked just by chance. The HQL grammar is specified here. As you can see from the HqlParser implementation the group
belong to so called weak keywords (see the weakKeywords()
method). So, the first query was tokenized in the following way:
SELECT group --> selectClause
FROM FOO_Group group --> fromClause (FROM^ { weakKeywords(); }) ...
WHERE group.valid = :valid --> whereClause
ORDER BY group.date --> orderByClause
But the second one:
SELECT group --> selectClause
FROM FOO_User user --> fromClause FROM^ { weakKeywords(); }
JOIN user.group ----> fromJoin ... JOIN^ (FETCH)? joinPath (asAlias)? ...
group --> problem !!!
WHERE group.valid = :valid
ORDER BY group.date