【问题标题】:Enumerations in HibernateHibernate 中的枚举
【发布时间】:2010-09-29 20:17:04
【问题描述】:

在 DAO 中拥有一个值来自 Java 枚举的字段通常很有用。一个典型的例子是登录 DAO,您通常有一个字段将用户描述为“NORMAL”或“ADMIN”。在 Hibernate 中,我将使用以下 2 个对象以(半)类型安全的方式表示这种关系:

class User {
    String username;
    String passwd;
    UserType type;
}

class UserType {
    private enum Type {ADMIN, NORMAL};
    private String type;

    //Setters/Getters for Hibernate
    public void setType(String type);
    public String getType();

    //Setters/Getters for user
    public void setUserType(UserType.Type t);
    public UserType.Type getUserType();

    public static UserType fromType(UserType.Type t);
}

这可行,但我发现 UserType 类很丑陋,并且需要太多官僚作风才能存储几个值。理想情况下,Hibernate 应该直接支持枚举字段,并会创建一个额外的表来存储枚举值。

我的问题是:有没有办法直接映射 Hibernate 中的枚举类?如果不是,我表示枚举的模式是否足够好,或者我错过了什么?人们还使用哪些其他模式?

【问题讨论】:

    标签: java hibernate dao


    【解决方案1】:

    来自 Hibernate 文档:http://www.hibernate.org/272.html

    您可以为每个枚举创建一个新的 typedef,并在属性标签中引用 typedef。

    示例映射 - 内联 <type> 标记

      <property name='suit'>
        <type name="EnumUserType">
          <param name="enumClassName">com.company.project.Suit</param>
        </type>
      </property>
    

    示例映射 - 使用 &lt;typedef&gt;

      <typedef name="suit" class='EnumUserType'>
          <param name="enumClassName">com.company.project.Suit</param>
      </typedef>
    
      <class ...>
        <property name='suit' type='suit'/>
      </class>
    

    【讨论】:

    • 谢谢。我已经知道那个解决方案了。问题是它要求你所有的枚举都使用休眠内部类型,如果你像我一样使用 DAO 作为 DTO,这可能会导致问题。这里实际上描述了一个更好的解决方案:hibernate.org/273.html
    • 请注意,在较新的版本中,参数名称是enumClass,而不是enumClassName
    【解决方案2】:

    使用休眠或 JPA 注释:

    class User {
       @Enumerated(EnumType.STRING)
       UserType type
    }
    

    UserType 只是一个标准的 java 5 枚举。

    我无法想象这仅限于注释,但我实际上并不知道如何使用 hbm 文件执行此操作。我猜它可能非常依赖于版本,但我很确定需要休眠 3.2+。

    编辑:在 hbm 中是可能的,但有点乱,看看这个forum thread

    【讨论】:

    • 可以@Enumerated(EnumType.ORDINAL) 哪个映射到int 更有效?
    • 可能更有效,但我会把钱放在无法衡量真实系统中的差异上。如果您只执行@Enumerated,则 EnumType.ORDINAL 实际上是默认值。我认为大多数人(尤其是 DBA)倾向于更喜欢 DB 中的枚举名称。
    • 如何更改这些枚举的列长度?我尝试添加 Column 注释,但没有得到尊重?
    • 您需要将其作为另一个问题提出。
    • 使用 STRING 而不是 ORDINAL,因为它允许您向 Enum 添加其他元素而不管顺序如何。
    猜你喜欢
    • 1970-01-01
    • 2011-01-10
    • 1970-01-01
    • 2015-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-14
    相关资源
    最近更新 更多