2009-01-06 81 views
82

在DAO中有一个值来自Java枚举的字段通常很有用。一个典型的例子是登录DAO,其中通常有一个字段将用户表征为“NORMAL”或“ADMIN”。在Hibernate中,我将使用以下2个对象来表示(半)类型安全方式这个关系: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); 
} 

这工作,但我觉得用户等级和积分类ungly和需要太多的繁文缛节只是存放一对夫妇值。理想情况下,Hibernate应直接支持枚举字段,并创建一个额外的表来存储枚举值。

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

回答

110

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

用户类型仅仅是一个标准的Java 5枚举。

我无法想象这仅仅局限于注释,但我实际上并不知道如何使用hbm文件来做到这一点。它可能是非常依赖版本,我猜测,但我很确定,需要休眠3.2+。

编辑:有可能在一个HBM,但有点凌乱,看一下这个forum thread

15

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

您可以为每个枚举的一个新的typedef,并在属性标记引用类型定义。

实施例映射 - 直列<type>标签

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

实施例映射 - 使用休眠或JPA注释使用<typedef>

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

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

感谢。我已经知道这个解决方案。问题是它需要你所有的枚举都使用hibernate内部的类型,如果你像在我的情况那样使用DAO作为DTO的话,会导致问题。实际上在这里描述了一个更好的解决方案: http://www.hibernate.org/273.html – 2009-01-06 16:27:05

+1

请注意,在较新版本中,参数名称是“enumClass”而不是“enumClassName”。 – 2011-08-02 15:25:23