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 次 |
| 最近记录: |