【问题标题】:Hibernate map enum to varcharHibernate 将枚举映射到 varchar
【发布时间】:2012-04-08 00:48:48
【问题描述】:

假设我有这个枚举:

public enum TestEnum { EXAMPLE, FURTHER_EXAMPLE, LAST_EXAMPLE }

有了这个映射在.hbm:

<property name="testEnum" column="TEST_COLUMN">
    <type name="org.hibernate.type.EnumType">
        <param name="enumClass">p.a.c.k.TestEnum</param>
    </type>
 </property>

枚举以012 的形式发送到数据库。我希望在 varchar 列中将值存储为 EXAMPLEFURTHER_EXAMPLELAST_EXAMPLE

如何将枚举映射到 varchar 列?

【问题讨论】:

标签: hibernate enums hibernate-mapping varchar


【解决方案1】:

将此作为 EnumType 的参数添加:

<param name="type">12</param>

这是因为12 等价于java.sql.Types.VARCHAR

【讨论】:

  • 12 等价于 java.sql.Types.VARCHAR。
  • 我在浏览解决方案时看到了该值,但认为它是枚举的默认值。它不是很有描述性,看起来像一个神奇的值。谢谢!
【解决方案2】:

也许这更具描述性

<param name="useNamed">true</param>

【讨论】:

  • useNamed 自 4.2.0.Final 以来一直处于休眠状态,而 type 甚至在 3.1beta9 中也存在 link link
【解决方案3】:

你可以像这样使用注解:

public class MyClass {
    TestEnum testEnum;
    @column(name="TEST_COLUMN")
    @Enumerated(EnumType.STRING)
    public TestEnum getTestEnum(){
        this.testEnum;
    }
}

【讨论】:

  • 问题是hbm映射,而不是注释。
【解决方案4】:

如果您想将任何枚举的值作为 varchar 存储在数据库中,请按照以下步骤操作。

  1. Hibernate 提供了一个 UserTpe 接口。我们需要创建一个实现 UserType 接口的类。

    import java.io.Serializable;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Types;
    
    import org.hibernate.HibernateException;
    import org.hibernate.usertype.UserType;
    
    public class EnumUserType<E extends Enum<E>> implements UserType {
       private Class<E> clazz = null;
    
       protected EnumUserType(Class<E> c) {
           this.clazz = c;
       }
    
       private static final int[] SQL_TYPES = { Types.VARCHAR };
    
       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]);
    
           E 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);
       }
    }
    
  2. 假设我有一个 EncryptionStatus 枚举。

    import java.io.Serializable;
    import com.google.gwt.user.client.rpc.IsSerializable;
    
    public enum EncryptionStatus implements IsSerializable, Serializable {
        PLAIN, HASH, RE_HASH, SUPER_HASH, SUPER_REHASH, OPEN, ENCRYPT, RE_ENCRYPT
    }
    
  3. 我们需要创建一个类来扩展我们创建的 EnumUserType>。

    public class EncryptionStatusType extends EnumUserType<EncryptionStatus>{
    
       public  EncryptionStatusType() {     
           super(EncryptionStatus.class);
       }
    }
    
  4. 现在我们需要在 hbm.xml 文件中映射上面创建的类,而不是在数据库中将枚举值存储为 varchar 的 Enum 映射。例如,

<property name="secureStatus" type="com.nextenders.facadeimplementation.util.userenum.EncryptionStatusType" column="secure_status" />

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-23
    • 2012-09-04
    • 1970-01-01
    • 2018-04-11
    • 1970-01-01
    • 1970-01-01
    • 2019-08-14
    • 1970-01-01
    相关资源
    最近更新 更多