【问题标题】:Reserved keyword as identifier in JPA query保留关键字作为 JPA 查询中的标识符
【发布时间】:2020-06-24 15:08:44
【问题描述】:

我以这种方式定义了多个 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

这一次查询失败,Hibernate 声明 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

【问题讨论】:

    标签: sql hibernate jpa naming reserved-words


    【解决方案1】:

    您应该区分SQL 关键字JPQL/HQL 保留标识符

    您可以使用SQL quoted identifiers 作为列/表名称。

    但根据 JPA 规范(参见 4.4.1 标识符部分)

    保留标识符不得使用作为标识变量 或结果变量(参见第 4.8 节)。

    您的第一个查询是偶然的。 HQL 语法指定为here。从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
    

    【讨论】:

    • 好的,感谢您的见解和引用的语法。我知道,作为保留关键字,标识符group 可能是一个糟糕的选择。但是,我想知道为什么它仍然工作了一次,而另一次却失败了。我现在将groupg 都重命名为grp 以实现一致的命名方案。
    猜你喜欢
    • 2010-10-09
    • 1970-01-01
    • 2013-05-18
    • 2022-10-13
    • 2021-11-19
    • 2011-01-10
    • 1970-01-01
    相关资源
    最近更新 更多