休眠中的枚举


82

在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中映射枚举类?如果不是,我表示枚举的模式是否足够好?人们还会使用其他哪些模式?

Answers:


110

使用休眠或JPA批注:

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

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

我无法想象这仅限于注解,但我实际上不知道如何使用hbm文件。我猜这可能与版本有关,但是我很确定需要休眠3.2+。

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


3
@Enumerated(EnumType.ORDINAL)可以更有效地映射到int吗?
李志坚

4
可能会更有效,但是我会花钱无法测量实际系统中的差异。如果仅执行@Enumerated,则EnumType.ORDINAL实际上是默认值。我认为大多数人(尤其是DBA)倾向于在数据库中使用枚举名称。
Gareth Davis

1
如何更改这些枚举的列长?我尝试添加Column注释,但是没有兑现?
Kannan Ekanath'9

2
您需要问另一个问题。
Gareth Davis

2
使用STRING而不是ORDINAL,因为它允许您将附加元素添加到Enum中,而不考虑顺序。
马修·道门

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>

谢谢。我已经知道该解决方案。问题在于,它要求您所有的枚举都使用休眠内部类型,如果像我这样将DAO用作DTO,则可能会导致问题。实际上,这里描述了一个更好的解决方案: hibernate.org/273.html
Georgios Gousios 2009年

1
请注意,在新版本中的参数名是enumClass代替enumClassName
瑞安·兰斯福德
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.