【问题标题】:Upgrading to Hibernate 5: how to get type mapping now that TypeResolver is deprecated升级到 Hibernate 5:不推荐使用 TypeResolver 后如何获取类型映射
【发布时间】:2021-07-29 03:22:39
【问题描述】:

我正在使用一个较旧的代码库,该代码库有很多使用这样的枚举的实体(当前使用 Hibernate 3),并带有一个“生成”的 GenericEnumUserType 类:

@Entity
@Table(name = "dog")
@TypeDefs({
    @TypeDef(name = "DogEnumType",
    typeClass = com.GenericEnumUserType.class,
    parameters = {
            @Parameter(name = "enumClass", value = "com.DogStateEnum"),
            @Parameter(name = "identifierMethod", value = "value"),
            // could return different type depending on enum
            @Parameter(name = "valueOfMethod", value = "fromValue")
    }
)
})
public class Dog implements Serializable {

...

    @Type(type = "DogEnumType")
    public DogStateEnum getDogState() {
        return this.dogState;
    }

...

GenericEnumUserType(想法是将 valueOf 方法的 java 返回类型映射到适当的 sql 类型):

public class GenericEnumUserType implements UserType, ParameterizedType {

...
    private Method valueOfMethod;
    private int[] sqlTypes;
...

    public void setParameterValues(Properties parameters) {
        // Something along the lines of:
        String enumClassName = parameters.getProperty("enumClass");

        enumClass = Class.forName(enumClassName).asSubclass(Enum.class);
      
        String identifierMethodName = parameters.getProperty("identifierMethod");

        identifierMethod = enumClass.getMethod(identifierMethodName);
        identifierType = identifierMethod.getReturnType();

        // TypeResolver is now deprecated!!
        type = (AbstractSingleColumnStandardBasicType<? extends Object>) new TypeResolver().heuristicType(identifierType.getName(), parameters);

        sqlTypes = new int[] { ((AbstractSingleColumnStandardBasicType<?>) type).sqlType() };

        String valueOfMethodName = parameters.getProperty("valueOfMethod");

        valueOfMethod = enumClass.getMethod(valueOfMethodName, new Class[] { identifierType });
    }
...

既然 TypeResolver 已被弃用且没有替代品,那么查找从 java 类型到 sql 类型的映射的适当方法是什么?如果这是不可能的,迁移此类代码的推荐方法是什么?

我可以看到 Hibernate 现在有 org.hibernate.type.EnumType 但实现假定序数/字符串可能很好,但重构更大(还有超过 1 个通用枚举)。

【问题讨论】:

    标签: java hibernate hibernate-5.x


    【解决方案1】:

    现在 Hibernate 映射枚举开箱即用,这很可能是不必要的。除非在这里实现了一些不寻常的东西,否则这些枚举要么以其字符串表示形式保存,要么以其序数保存。

    默认情况下,Hibernate 将假定您正在映射序数。如果GenericEnumUserType 也这样做,您可以简单地删除@Type(type = "DogEnumType") 注释。请注意,在这种情况下,在枚举中添加/删除值时需要小心。

    否则你需要使用@Enumerated注解告诉Hibernate你想要将String值存储在数据库中:

    @Enumerated(EnumType.STRING)
    public DogStateEnum getDogState() {
        return this.dogState;
    }
    

    您可以删除@TypeDefs 注释。

    请注意,当枚举用作映射键时,还有@MapKeyEnumerated 注释。

    【讨论】:

    • 我仍然想知道应该如何为非枚举类型迁移 TypeDefs,因为弃用没有给出任何解决方案 appart from "6.0 将引入一系列新的类型安全注释以达到相同的目的"
    • Hibernate 6 仍处于测试阶段,但我认为您可以参考更新后的文档:docs.jboss.org/hibernate/orm/6.0/userguide/html_single/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-11
    • 2021-11-10
    • 1970-01-01
    • 2021-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多