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?
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.
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.
@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.
In order to map a Many-to-Many relationship we'll use the @ManyToMany annotation.
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.
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); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With