我上的Java 7和JPA与一个UserType休眠/ JPA实体属性不正确加载
运行的Hibernate。4.3.11.Final我创建了一个用户类型编组/解组一个Java枚举对象数据库将其存储为SMALLINT。
枚举是地址对象的一个属性,表示地址的一般区域/地点。
我的问题是这样的:
当我加载地址直接例如为:
Address anAddress = session.get(Address.class, 123L);
它加载很好,我可以访问AreaEnum例如
assert anAddress.getArea() != null; // ALL GOOD
然而,当我通过从另一实体的集合关系访问的地址的AreaEnum没有编组并返回一个null
,例如
Person aPerson = session.get(Person.class, 5L);
assert aPerson.getAddress().getArea() != null; // FAILS HERE
其他标准属性(具有简单的列定义注释)被填充好。
我的区域属性的注释是这样的:
public class Address {
...
@Type(type = "mls.dao.util.HibernateAreaEnumType")
@Column(name = "are_id", nullable = false, updatable = true, columnDefinition = "SMALLINT")
public AreaEnum getArea() {
return this.area;
}
@Override
public void setArea(AreaEnum _area) {
this.area = _area;
}
...
}
这里是HibernateAreaEnumType用户类型类:
public class HibernateAreaEnumType implements UserType {
private final Method parseMethod;
private final Class clazz;
public HibernateAreaEnumType() {
clazz = AreaEnum.class;
try {
// this is a static method
this.parseMethod = clazz.getMethod("parseEnum", Long.class);
} catch (Exception e) {
throw new IllegalStateException("issue with trying get the parse method of this enum class: " + clazz.getSimpleName(), e);
}
}
@Override
public Object nullSafeGet(ResultSet _rs, String[] _names, SessionImplementor _sessionImplementor, Object _owner) throws HibernateException, SQLException {
Object result = null;
if (!_rs.wasNull()) {
Long enumId = (long) _rs.getInt(_names[0]);
try {
result = this.parseMethod.invoke(null, enumId);
} catch (Exception e) {
throw new HibernateException("issue trying to method to parse value to make enum: " + enumId, e);
}
}
return result;
}
@Override
public void nullSafeSet(PreparedStatement _ps, Object _value, int _index, SessionImplementor _sessionImplementor) throws HibernateException, SQLException {
try {
if (null == _value) {
_ps.setNull(_index, Types.SMALLINT);
} else {
_ps.setLong(_index, ((MarshallableIdEnum) _value).getId());
}
} catch (ClassCastException e) {
throw new IllegalStateException(this.getClass().getName() + ", issue: " + _value + "/" + _index, e);
}
}
private static final int[] SQL_TYPES = {Types.SMALLINT};
public int[] sqlTypes() {
return SQL_TYPES;
}
public Class returnedClass() {
return this.clazz;
}
@Override
public Object deepCopy(Object value) throws HibernateException {
return value;
}
@Override
public boolean isMutable() {
return false;
}
@Override
public Object assemble(Serializable cached, Object owner) throws HibernateException {
return cached;
}
@Override
public Serializable disassemble(Object value) throws HibernateException {
return (Serializable) value;
}
@Override
public Object replace(Object original, Object target, Object owner) throws HibernateException {
return original;
}
@Override
public int hashCode(Object x) throws HibernateException {
return x.hashCode();
}
@Override
public boolean equals(Object x, Object y) throws HibernateException {
return (x == y) || ((null != x) && (null != y) && x.equals(y));
}
}
在地址表中的区域栏定义为:
+--------------+-----------------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+-----------------------+------+-----+-------------------+-----------------------------+ |
| are_id | smallint(5) unsigned | YES | MUL | NULL |
+--------------+-----------------------+------+-----+-------------------+-----------------------------+
只是为了澄清表中的数据。
通过单步执行代码,似乎在HibernateAreaEnumType中rs.wasNull()
返回true
,但查看从sql select返回的实际数据(使用p6spy),表明区域枚举信息存在。
任何帮助非常感激