【问题标题】:Adding an enum as a class property in HBM在 HBM 中添加枚举作为类属性
【发布时间】:2010-12-26 04:23:24
【问题描述】:

我正在尝试在 HBM 文件中创建一个包含枚举作为字段的类。

HBM 与此类似:

<class name="a.b.c.myObject" table="OBJECT" >
       <property name="myEnum" column="EXAMPLE" type="a.b.c.myEnum" />
</class>

假设这是枚举:

public enum myEnum{
    a, b, c;
}

问题在于,我希望在数据库中看到该枚举(a、b 或 c)的字符串值,但我得到了该字段的原始数据。

我该如何解决?

【问题讨论】:

标签: hibernate enums hibernate-mapping hbm


【解决方案1】:

类似于@monim 的回答,但更优雅的方式:

<class name="a.b.c.myObject" table="OBJECT">
    <property name="myEnum" column="EXAMPLE">
        <type name="org.hibernate.type.EnumType">
            <param name="enumClass">a.b.c.myEnum</param>
            <param name="useNamed">true</param>
        </type>       
    </property>
</class>

【讨论】:

    【解决方案2】:

    只需编辑@Emmanuel Bourg 答案并像这样添加另一个&lt;param&gt;

    <class name="a.b.c.myObject" table="OBJECT">
        <property name="myEnum" column="EXAMPLE">
            <type name="org.hibernate.type.EnumType">
                <param name="enumClass">a.b.c.myEnum</param>
                <param name="type">12</param>
            </type>       
        </property>
    </class>
    

    12 等价于java.sql.Types.VARCHAR

    【讨论】:

    • 哪个对性能更好? varchar 还是 int 序数?我必须对枚举进行查询。
    • 如果你有索引,它可能是一个清洗。注意,如果该列是数据库中的 VARCHAR 或其同类,休眠将自动使用命名值,不需要useNamed(但如果休眠自己创建数据库,它将默认使用序数整数......谢谢一致,休眠)
    【解决方案3】:

    这是 Hibernate 3.6.x 的解决方案:

    <class name="a.b.c.myObject" table="OBJECT">
      <property name="myEnum" column="EXAMPLE">
        <type name="org.hibernate.type.EnumType">
          <param name="enumClass">a.b.c.myEnum</param>
        </type>       
      </property>
    </class>
    

    【讨论】:

    • 由于 Hibernate 4.1.7 使用条件进行查询不再适用于这种方法。由于此错误,无法更新到最新版本。
    • 这很好用,但不要尝试使用“嵌套类”(另一个类中的枚举),它似乎不起作用,但普通的公共枚举可以。
    【解决方案4】:

    出于不明原因,Hibernate 开发人员坚持保持 Hibernate 内核与 Java5 之前的版本兼容,这意味着不支持枚举。当您尝试持久化 Enum 字段时,它只是对其进行序列化,然后您将获得二进制数据。

    如果您想使用 .hbm 映射配置来持久化枚举,则必须为要处理的每种枚举类型创建和配置自定义 UserType,这既乏味又烦人。 Hibernate documentation wiki 有很多例子,其中许多似乎相互矛盾,其中一些甚至有效。

    不过,如果您使用 Hibernate 注释,您将获得完整的 java5 支持,包括自动处理 java5 枚举。你必须做一个或另一个,这真是太遗憾了。

    【讨论】:

      【解决方案5】:

      1) 简单的解决方案:使用Hibernate Annotations 而不是基于 XML 的映射。枚举支持is built-in:

      @Entity
      public class MyObject {
        @Enumerated(EnumType.STRING)
        @Column(name="EXAMPLE")
        private MyEnum myEnum;
      }
      

      2) 如果您不能使用注解,您仍然可以使用它们在基于 XML 的映射中提供的 EnumType。在部署期间,您确实需要在类路径中有适当的hibernate-annotations.jar,但没有编译时依赖性:

      <class name="a.b.c.myObject" table="OBJECT" >
        <property name="myEnum" column="EXAMPLE" type="org.hibernate.type.EnumType"/>
      </class>
      

      【讨论】:

      • “也一样”是什么意思?您将“字段的原始数据”存储在数据库中是什么意思?注意上面的“type”属性必须指向一个实际的Hibernate类型;不要像你在问题中指定的那样去你的枚举类。后者是非法的。
      • 第二个例子似乎没有告诉它使用哪个 Enum 类 [?]
      • 我厌倦了用 Hibernate 蹩脚的快捷方式污染我的代码
      【解决方案6】:

      您需要使用 UserType 来有效地持久化:https://www.hibernate.org/265.html

      【讨论】:

      • 这是一种相当过时的方法;创建所有这些额外的自定义类型是不必要的。
      猜你喜欢
      • 2020-05-11
      • 1970-01-01
      • 2022-12-14
      • 1970-01-01
      • 1970-01-01
      • 2013-03-27
      • 2010-12-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多