Я бегом гибернации 4.3.11.Final на Java 7 и JPAHibernate/JPA атрибут объекта с UserType не загружен правильно
Я создал UserType маршал/распаковать объект Перечисления Java в базу данных сохраняя его как SMALLINT.
Перечисление является атрибутом объекта Address и представляет собой общую область/местонахождение адреса.
Моя проблема заключается в следующем:
Когда я загружаю адрес непосредственно например .:
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
Другие стандартные атрибуты (имеющие простые аннотации определения столбцов) заполнены в порядке.
Мои аннотации для атрибута Area, как это:
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 UserType:
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) показывает, что информация область перечисления есть.
Любая помощь действительно оценили