Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mapping enum to a table with hibernate annotation

I have a table DEAL and a table DEAL_TYPE. I would like to map this code:

public class Deal {    DealType type; }  public enum DealType {    BASE("Base"), EXTRA("Extra"); } 

The problem is that the data already exist in the database. And I'm having a hard time mapping the classes to the database.

The database looks something like that:

   TABLE DEAL {       Long id;       Long typeId;    }     TABLE DEAL_TYPE {        Long id;        String text;    } 

I know I could use a simple @OneToMany relationship from deal to deal type, but I would prefer to use an enum. Is this possible?

I almost got it working by using a EnumType.ORDINAL type. But unfortunately, my IDs in my deal type table are not sequential, and do not start at 1.

Any suggestions?

like image 748
Thierry-Dimitri Roy Avatar asked Apr 09 '09 20:04

Thierry-Dimitri Roy


People also ask

How annotate enum in hibernate?

You can reference the class of your enum type in a @Type annotation on your entity attribute. This is a good approach if you only use the type on one entity attribute. When you use this mapping, Hibernate uses the EnumTypePostgreSql to map the Rating value to a PostgreSQL-specific enum type.

What annotation is used if enum is used in an entity?

The most common option to map an enum value to and from its database representation in JPA before 2.1 is to use the @Enumerated annotation.

What is the use of @entity annotation in hibernate?

@Entity annotation marks this class as an entity. @Table annotation specifies the table name where data of this entity is to be persisted. If you don't use @Table annotation, hibernate will use the class name as the table name by default.

Which annotation is used for mapping is a relationship in hibernate?

In order to map a Many-to-Many relationship we'll use the @ManyToMany annotation.


2 Answers

Hibernate is kind of terrible at Enums. It's a strange failing of an otherwise pretty good ORM. The "easiest" way to get around it is to declare your Enum a custom hibernate type. Fortunately, Hibernate wrote an example implementation which you can crib verbatim into your app:

http://www.hibernate.org/265.html

They even include instructions on how to use it. This is the pattern I use whenever I end up with the need to persist enums.

like image 104
Brandon Yarbrough Avatar answered Sep 20 '22 03:09

Brandon Yarbrough


I've created a similar class like the one suggested by hibernate only that is configurable and there is no need to create a new type only for this persistence.

Can be used like

@Type(type = "ro.raisercostin.hibernate.EnumUserType", parameters = @Parameter(name = "type", value = "DealType")) DealType dealType; 

I added an implementation of ParameterizedType to support the passed parameter.

public class EnumUserType implements UserType, ParameterizedType {      private static final int[] SQL_TYPES = { Types.VARCHAR };     private Class clazz = null;      public EnumUserType() {     }      @Override     public void setParameterValues(Properties parameters) {         String className = (String) parameters.get("type");         try {             this.clazz = Class.forName(className);         } catch (ClassNotFoundException e) {             throw new RuntimeException("Couldn't get the class for name [" + className + "].", e);         }     }      public int[] sqlTypes() {         return SQL_TYPES;     }      public Class returnedClass() {         return clazz;     }      public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner) throws HibernateException,             SQLException {         String name = resultSet.getString(names[0]);         Object result = null;         if (!resultSet.wasNull()) {             result = Enum.valueOf(clazz, name);         }         return result;     }      public void nullSafeSet(PreparedStatement preparedStatement, Object value, int index) throws HibernateException,             SQLException {         if (null == value) {             preparedStatement.setNull(index, Types.VARCHAR);         } else {             preparedStatement.setString(index, ((Enum) value).name());         }     }      public Object deepCopy(Object value) throws HibernateException {         return value;     }      public boolean isMutable() {         return false;     }      public Object assemble(Serializable cached, Object owner) throws HibernateException {         return cached;     }      public Serializable disassemble(Object value) throws HibernateException {         return (Serializable) value;     }      public Object replace(Object original, Object target, Object owner) throws HibernateException {         return original;     }      public int hashCode(Object x) throws HibernateException {         return x.hashCode();     }      public boolean equals(Object x, Object y) throws HibernateException {         if (x == y) {             return true;         }         if ((null == x) || (null == y)) {             return false;         }         return x.equals(y);     } } 
like image 20
raisercostin Avatar answered Sep 19 '22 03:09

raisercostin