views:

1552

answers:

2

I need to map the enums which didn't implement the interface beforehand to the existing database, which stores enums in the same table as the owner class using the @Enumerated(EnumType.STRING).

class A {
    HasName name;
}

interface HasName {
    String getName();
}

enum X implements HasName {
    John, Mary;

    public String getName() { return this.name(); }
}

enum Y implements HasName {
    Tom, Ann;

    public String getName() { return this.name(); }
}

How the mapping should be handled in this case? Persisting to the database doesn't change as all of the enums implementing the interface will have different values, but I'm not sure how the objects should be retrieved from the DB (do I need a custom mapper, which will try to instantiate an enum using the specified enum classes? Does Hibernate natively support this functionality?).

+3  A: 

It's possible to create a custom UserType (e.g. this one) and use it from your mappings

<property name="type" not-null="true">
  <type name="at.molindo.util.hibernate.EnumUserType">
    <param name="enumClass">
      com.example.MyEnum
    </param>
  </type>
</property>
sfussenegger
In my case I don't know what the class of the enum will be. When instantiating `A`, Hibernate will need to pick one of the {X, Y} enums.
dm3
It shouldn't be to difficult to tweak the example UserType implementation to your needs. For instance, instead of storing the value only, you might also store the class (e.g. com.example.X.John or X.John, but than you'll need a mapping from X to com.example.X)
sfussenegger
Means I need a custom mapper (didn't see your link to pastebin). Thanks for the answer.
dm3
+2  A: 

Hibernate provides org.hibernate.type.EnumType to map Enumerated types. For instance,

package com.igalia.enumerates;

public enum Status {
   BUSY,
   AVAILABLE;
}

package com.igalia.entities;

class MyClass {
   private Status status;
}

Then, do your Hibernate mapping as follows:

<class name="MyClass">
   <id name="id">
      <generator class="native"/>
   </id>

   <property name="status">
      <type name="org.hibernate.type.EnumType">
         <param name="enumClass">com.igalia.enumerates.Status</param>
      </type>
   </property>
</class>

And that's it. If you prefer to use JPA annotations instead of hbm.xml, use @Enumerated(EnumType.STRING). Check it here:

http://stackoverflow.com/questions/417062/enumerations-in-hibernate

Diego Pino