Hibernate中的枚举,作为枚举进行持久化

42

在我的MySQL数据库中,有一列 "gender enum('male','female')"。

我创建了我的枚举类型 "com.mydomain.myapp.enums.Gender",并在我的Person实体中定义了 "Gender gender"。

现在我想保留MySQL数据库中的枚举类型,但是当我启动我的应用程序时,我收到以下错误信息:

  

MyApp.Person的列Gender的列类型错误。找到:enum,期望:integer

为什么会出现这种情况?这相当于如果我用 "@Enumerated(EnumType.ORDINAL)"注释了我的 "Gender gender",但实际上我没有这样做。EnumType似乎只能是ORDINAL或STRING,那么该如何指定它应该把字段视为枚举而不是整数呢?(虽然它们之间没有太大区别,但足以让它感到困扰。)


发送整数应该可以工作。男性 = 1,女性 = 2。 - Cherian
使用Hibernate,您建议我如何注释我的实体类来实现这一点?我已经尝试明确定义我的枚举值“public enum Gender(MALE(1),FEMALE(2); }”,但错误输出没有任何区别。 - niklassaers
5个回答

32

如果您为Hibernate提供了一个列定义,它将不会尝试猜测:

@Column(columnDefinition = "enum('MALE','FEMALE')")
@Enumerated(EnumType.STRING)
private Gender gender;

如果您没有依赖Hibernate来生成模式,那么您甚至不必为columnDefinition提供实际值。这样,您就可以消除需要保持值同步的情况。只需确保您的Java枚举与Liquibase或SQL脚本保持同步:

@Column(columnDefinition = "enum('DUMMY')")
@Enumerated(EnumType.STRING)
private ManyValuedEnum manyValuedEnum;

31
我的理解是MySQL枚举类型非常专有,Hibernate对其支持不好,可以看到Gavin King的这条评论(虽然相关问题有点不同,但这不是重要部分)。
因此,我认为你需要使用自己的UsereType,并建议使用Java 5 EnumUserType中的灵活解决方案-可工作版本(请参见Appfuse的Java 5 Enums Persistence with Hibernate示例)。
个人而言,我会忘记使用MySQL枚举,我不相信其中的“好处”值得一试(请参阅这个答案以获取更多详细信息)。

19

尝试使用@Enumerated(EnumType.STRING),并像这样定义您的枚举

enum Gender {
  male,
  female
}

请注意小写值。

这将至少适用于VARCHAR列。它将把枚举作为字符串“male”或“female”存储。


5
我正在使用枚举类型列,而不是字符串类型。 - niklassaers
5
你实际上尝试过我的建议了吗?MySQL中的性别类型可能只是在varchar或char列周围包装/语法糖。 - Juha Syrjälä

5

我不确定为什么这个内容没有在Hibernate文档中,但是你可以这样做:

<property name="type" column="type" not-null="true">
    <type name="org.hibernate.type.EnumType">
        <param name="enumClass">com.a.b.MyEnum</param>
        <param name="type">12</param>
        <!-- 12 is java.sql.Types.VARCHAR -->
    </type> 
</property>

谢谢,这对于MySQL的ENUM列很有效,尽管12是针对VARCHAR的。 - arun
2
如何使用注释来完成这个任务? - rajadilipkolli

4

虽然这不适用于此情况,但如果有人正在使用XML映射:

<property name="state" column="state" not-null="true">
  <type name="org.hibernate.type.EnumType">
    <param name="enumClass">com.myorg.persistence.data.State</param>
  </type>
</property>

数据库列类型必须是数字类型,例如在MySQL上使用tinyint,才能使读取序数值成为可能。


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