Hibernate中的枚举类型

82

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

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中直接映射枚举类?如果没有,那么我表示枚举的模式是否足够好,或者我是否遗漏了什么?人们使用哪些其他模式?

2个回答

111

使用 Hibernate 或 JPA 注解:

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

UserType是一个标准的Java 5枚举类型。

我无法想象这仅仅局限于注释,但实际上我不知道如何在hbm文件中实现这一点。这可能与版本有关,我猜测需要Hibernate 3.2或更高版本。

编辑:在hbm中也是可能的,但有点混乱,请查看论坛主题


3
将@Enumerated(EnumType.ORDINAL)映射为int会更有效吗? - Lee Chee Kiam
4
可能更有效率,但我敢打赌在实际系统中无法测量到区别。如果只使用@Enumerated,则EnumType.ORDINAL实际上是默认值。我认为大多数人(尤其是数据库管理员)倾向于在数据库中使用枚举名称。 - Gareth Davis
1
我该如何更改这些枚举的列长度?我尝试添加Column注释,但没有生效? - Kannan Ekanath
2
你需要将这个问题作为另一个问题来询问。 - Gareth Davis
2
使用STRING而不是ORDINAL,因为它允许您添加枚举的其他元素,而不考虑顺序。 - Matthew Daumen

14

根据 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>

例子映射 - 使用 <typedef>

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

  <class ...>
    <property name='suit' type='suit'/>
  </class>

谢谢。我已经知道那个解决方案了。问题在于它要求所有的枚举类型都使用 hibernate-internal 类型,如果你像我这样将 DAO 用作 DTO,则可能会出现问题。更好的解决方案实际上在这里描述:http://www.hibernate.org/273.html - Georgios Gousios
1
请注意,在较新版本中,参数名称为enumClassName的地方已更改为enumClass - Ryan Ransford

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接