18

I am trying to create a class in HBM file which contains an Enum as a field.

The HBM is similar to this:

<class name="a.b.c.myObject" table="OBJECT" >
       <property name="myEnum" column="EXAMPLE" type="a.b.c.myEnum" />
</class>

and let's say that this is the Enum:

public enum myEnum{
    a, b, c;
}

The problem is that in the DB I expected to see the String value of that enum (a,b or c) but instead I got the raw data of that field.

How can I solve that?

Avi Y
  • 2,456
  • 4
  • 29
  • 35

6 Answers6

17

Here is the solution with Hibernate 3.6.x :

<class name="a.b.c.myObject" table="OBJECT">
  <property name="myEnum" column="EXAMPLE">
    <type name="org.hibernate.type.EnumType">
      <param name="enumClass">a.b.c.myEnum</param>
    </type>       
  </property>
</class>
Emmanuel Bourg
  • 9,601
  • 3
  • 48
  • 76
  • Since Hibernate 4.1.7 querying using criteria does not works with this approach anymore. Cannot update to newest version because of this bug. – djmj Aug 26 '13 at 02:02
  • This works well, but don't try it with a "nested class" (an enum inside another class) that doesn't seem to work but a normal public enum did. – rogerdpack Sep 14 '15 at 22:53
8

Similar to @monim answer, but more elegant way:

<class name="a.b.c.myObject" table="OBJECT">
    <property name="myEnum" column="EXAMPLE">
        <type name="org.hibernate.type.EnumType">
            <param name="enumClass">a.b.c.myEnum</param>
            <param name="useNamed">true</param>
        </type>       
    </property>
</class>
eitann
  • 1,203
  • 10
  • 23
7

1) Easy solution: use Hibernate Annotations instead of XML-based mappings. Enum support is built-in:

@Entity
public class MyObject {
  @Enumerated(EnumType.STRING)
  @Column(name="EXAMPLE")
  private MyEnum myEnum;
}

2) If you can't use annotations, you can still use the EnumType they provide in XML-based mappings. You do need to have appropriate hibernate-annotations.jar in your classpath during deployment but there's no compile-time dependency:

<class name="a.b.c.myObject" table="OBJECT" >
  <property name="myEnum" column="EXAMPLE" type="org.hibernate.type.EnumType"/>
</class>
ChssPly76
  • 99,456
  • 24
  • 206
  • 195
  • "Does the same" meaning what? What did you mean by "raw data of the field" being stored in the database? Note that "type" attribute above must point to an actual Hibernate type; not to your enum class like you've specified in the question. The latter is illegal. – ChssPly76 Dec 14 '09 at 16:23
  • 1
    The second example seems to be missing telling it which Enum class to use [?] – rogerdpack Sep 14 '15 at 22:43
  • 1
    I am tired of polluting my code with Hibernate crappy shortcuts – MonoThreaded Jun 17 '16 at 19:56
6

Just editing @Emmanuel Bourg answer and adding another <param> like this:

<class name="a.b.c.myObject" table="OBJECT">
    <property name="myEnum" column="EXAMPLE">
        <type name="org.hibernate.type.EnumType">
            <param name="enumClass">a.b.c.myEnum</param>
            <param name="type">12</param>
        </type>       
    </property>
</class>

12 is equivilant to java.sql.Types.VARCHAR

monim
  • 3,427
  • 3
  • 23
  • 36
  • Which is better for better for performance? varchar or int ordinal? I have to make queries on enum. – Kuldeep Yadav Sep 09 '16 at 04:28
  • If you have indexes it's probably a wash. NB that if the column is a VARCHAR or its ilk in the DB, hibernate will automatically use the named values, no `useNamed` needed (but if hibernate creates the DB itself, it will default to using ordinal integers...thanks for being consistent, hibernate) – rogerdpack Jun 25 '21 at 20:28
3

For reasons that remain obscure, the Hibernate developers insist on keeping the Hibernate core compatible with pre-Java5, and that means no enum support. When you try to persist an Enum field, it just serializes it, and you get binary data.

If you want to persist enums using an .hbm mapping configuration, you have to create and configure a custom UserType for each enum type you want to handle, which is tedious and irritating. The Hibernate documentation wiki has plenty of examples, many of which seem to contradict each other, and some of which even work.

If you use Hibernate annotations, though, you get full java5 support, including automatic handling of java5 enums. It's just a real shame that you have to do one or the other.

skaffman
  • 398,947
  • 96
  • 818
  • 769
0

You need to use a UserType to persist that efficiently: https://www.hibernate.org/265.html

cherouvim
  • 31,725
  • 15
  • 104
  • 153