我上的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),表明區域枚舉信息存在。
任何幫助非常感激