Зарезервированное ключевое слово в качестве идентификатора в запросе JPA - PullRequest
1 голос
/ 12 марта 2020

Я определил несколько именованных запросов JPA следующим образом:

SELECT group FROM FOO_Group group WHERE group.valid = :valid ORDER BY group.date

Несмотря на то, что group является зарезервированным ключевым словом в SQL, это никогда не беспокоило Hibernate.

Теперь, однако мне пришлось определить именованный запрос, объединяющий две таблицы:

SELECT group FROM FOO_User user JOIN user.group group WHERE group.valid = :valid ORDER BY group.date

На этот раз запрос завершается неудачно, и в спящем режиме говорится, что ожидалось BY (как в GROUP BY), но WHERE было найдено.

Я знаю, что использование зарезервированных ключевых слов в качестве имен столбцов, таблиц или сущностей, как правило, является плохой идеей. Но мне интересно, почему это не вызвало никаких проблем в моих старых запросах, но теперь не удается в запросе присоединения. Есть ли синтаксис, который позволяет мне использовать group в новом запросе? Я попытался JOIN user.group AS group, но это не сработало, как ожидалось.

Сейчас все, что я могу сделать, это переименовать идентификатор:

SELECT g FROM FOO_User user JOIN user.group g WHERE g.valid = :valid ORDER BY g.date

1 Ответ

1 голос
/ 14 марта 2020

Вы должны различать guish SQL ключевые слова и Зарезервированные идентификаторы JPQL / HQL .

Вы можете использовать SQL цитируемые идентификаторы для имен столбцов / таблиц.

Но согласно спецификации JPA (см. раздел 4.4.1 Идентификаторы )

Зарезервированные идентификаторы нельзя использовать в качестве идентификационных или результирующих переменных (см. Раздел 4.8).

Ваш первый запрос сработал случайно. Грамматика HQL указана здесь . Как видно из реализации HqlParser , group относятся к так называемым слабым ключевым словам (см. Метод weakKeywords()). Итак, первый запрос был размечен следующим образом:

SELECT group               --> selectClause                
FROM FOO_Group group       --> fromClause   (FROM^ { weakKeywords(); }) ...
WHERE group.valid = :valid --> whereClause
ORDER BY group.date        --> orderByClause

Но второй:

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
...