Chr*_*311 5 java mapping enums hibernate
我有一个具有列状态的实体。存储在数据库中的状态是活动的和非活动的(还有更多)。我给自己写了一个如下的枚举
public enum State {
    ACTIVE("active"), INACTIVE("inactive");
    private String state;
    private State(String state) {
        this.state = state;
    }
}
Run Code Online (Sandbox Code Playgroud)
该实体看起来像:
@Entity
@Table(name = "TEST_DB")
public class MyEntity implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @Column(name = "ID")
    private Integer id;
    @Enumerated(EnumType.STRING)
    @Column(name = "STATE", nullable = false)
    private Integer state;
    // constructor, getter, setter
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,我收到以下错误消息:
javax.ejb.EJBTransactionRolledbackException: Unknown name value [active] for enum class [state]
Run Code Online (Sandbox Code Playgroud)
是否可以对枚举进行不区分大小写的休眠映射?
我面临着类似的问题,并找到了简单的答案。
您可以执行以下操作:
@Column(name = "my_type")
@ColumnTransformer(read = "UPPER(my_type)", write = "LOWER(?)")
@Enumerated(EnumType.STRING)
private MyType type;
Run Code Online (Sandbox Code Playgroud)
(你不需要“写入” @ColumnTransformer- 对我来说这是为了向后兼容,因为我的行只有小写。没有writeHibernate 将在相同的情况下写入枚举,就像在枚举常量中的代码中一样)
您可以使用 hibernate 注释将枚举映射为 ORDINAL 或 STRING,例如:
@Enumerated(EnumType.ORDINAL)
private State state;
Run Code Online (Sandbox Code Playgroud)
序数映射将枚举在数据库中的序数位置。如果更改代码中枚举值的顺序,这将与现有数据库状态发生冲突。字符串映射将枚举的大写名称放入数据库中。如果重命名枚举值,则会遇到同样的问题。
如果您想定义自定义映射(如上面的代码),您可以创建一个org.hibernate.usertype.UserType显式映射枚举的实现。
首先,我建议对您的枚举进行一些更改,以使以下内容成为可能:
public enum State {
    ACTIVE("active"), INACTIVE("inactive");
    private String stateName;
    private State(String stateName) {
        this.stateName = stateName;
    }
    public State forStateName(String stateName) {
        for(State state : State.values()) {
            if (state.stateName().equals(stateName)) {
                return state;
            }
        }
        throw new IllegalArgumentException("Unknown state name " + stateName);
    }
    public String stateName() {
        return stateName;
    }
}
Run Code Online (Sandbox Code Playgroud)
这是 UserType 的一个简单(!)实现:
public class StateUserType implements UserType {   
    private static final int[] SQL_TYPES = {Types.VARCHAR}; 
    public int[] sqlTypes() {   
        return SQL_TYPES;   
    }   
    public Class returnedClass() {   
        return State.class;   
    }   
    public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner) throws HibernateException, SQLException {   
        String stateName = resultSet.getString(names[0]);   
        State result = null;   
        if (!resultSet.wasNull()) {   
            result = State.forStateName(stateName);
        }   
        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, ((State)value).stateName());   
        }   
    }   
    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);   
    }   
}   
Run Code Online (Sandbox Code Playgroud)
那么映射将变为:
@Type(type="foo.bar.StateUserType")
private State state;
Run Code Online (Sandbox Code Playgroud)
有关如何实现 UserType 的另一个示例,请参阅:http://www.gabiaxel.com/2011/01/better-enum-mapping-with-hibernate.html
|   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           2605 次  |  
        
|   最近记录:  |