【问题标题】:Hibernate QuerySyntaxException with enum when hibernate.query.conventional_java_constants is set to false当 hibernate.query.conventional_java_constants 设置为 false 时,带有枚举的 Hibernate QuerySyntaxException
【发布时间】:2020-10-20 14:25:41
【问题描述】:

背景:使用 Java 8 和 Hibernate 5.3.9.Final 的 Java/Wildfly/Hibernate 应用程序。

我有一个这样的命名查询

  @NamedQuery(
    name = DailyStatement.GET_EXPORT_DATES_BY_ORGASTRUCTUREIDS_FOR_MISEXPORT,
    query =
            " SELECT d.orgaStructureId, MIN(d.workingDay), MAX(d.workingDay) "
                    + "   FROM DailyStatement d "
                    + "  WHERE d.orgaStructureId in (:orgaStructureIds) "
                    + "    AND d.misExportFlag = false "
                    + "    AND d.state = net.shop.ob.ptm.types.timerecord.EDailyStatmentsState.CLOSED "
                    + "    AND d.workingDay <= :maxWorkingDay "
                    + " GROUP BY d.orgaStructureId "

启动应用程序时出现错误

DailyStatement.getExportDatesByOrgaStructureIdsForMISExport 失败 因为:org.hibernate.hql.internal.ast.QuerySyntaxException: 无效路径: 'net.shop.ob.ptm.types.timerecord.EDailyStatmentsState.CLOSED' [ 选择 d.orgaStructureId, MIN(d.workingDay), MAX(d.workingDay) FROM net.shop.ob.ptm.dm.entities.DailyStatement d WHERE d.orgaStructureId in (:orgaStructureIds) AND d.misExportFlag = false AND d.state = net.shop.ob.ptm.types.timerecord.EDailyStatmentsState.CLOSED AND d.workingDay

引用的、据称错误的枚举如下所示

public enum EDailyStatmentsState {
    OPEN(0),
    ERROR(1),
    CLOSED(2);

    private int id;

    //(...)

如果我设置了hibernate参数就不会出现错误

hibernate.query.conventional_java_constants

假的

在persistence.xml 中。在博文https://vladmihalcea.com/the-performance-penalty-of-class-forname-when-parsing-jpql-and-criteria-queries/ 中解释了这个参数的含义。如果常量 EDailyStatmentsState.CLOSED 不遵循标准的 Java 命名约定,我会理解错误,但据我所知,确实如此。

由于性能原因,我想设置休眠选项

hibernate.query.conventional_java_constants

设置为 false 并修复错误的根本原因。这可能是什么原因造成的?

顺便说一句,这个问题不是重复的,例如这个问题QuerySyntaxException with enum 因为非标准的小写枚举命名导致了那里的错误,这与我的情况不同。

【问题讨论】:

    标签: java hibernate enums


    【解决方案1】:

    显然问题在于 Hibrnate 中类名的验证是使用类 org.hibernate.internal.util.ReflectHelper 中的以下正则表达式完成的:

    [a-z\d]+\.([A-Z]{1}[a-z\d]+)+\$?([A-Z]{1}[a-z\d]+)*\.[A-Z_\$]+
    

    这会导致具有两个连续大写字母的类无法验证。这是a known Hibernate bug (HHH-14059),它在Hibernate 内部是fixed,方法是将有问题的正则表达式替换为

    [a-z\d]+\.([A-Z]+[a-z\d]+)+\$?([A-Z]{1}[a-z\d]+)*\.[A-Z_\$]+
    

    我通过将类重命名为不包含连续的大写字母来解决此问题。

    这个问题也在 Hibernate 5.4.19 中得到修复。

    【讨论】:

      猜你喜欢
      • 2020-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-17
      • 1970-01-01
      • 2011-01-10
      • 2014-11-30
      • 2011-11-14
      相关资源
      最近更新 更多