2016-11-15 3 views
0

Я бегом гибернации 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) показывает, что информация область перечисления есть.

Любая помощь действительно оценили

ответ

0

Проблема заключалась в том, что я принципиально не понял, что указанный вызов ResultSet.wasNull().

А именно, что он «Сообщает, имеет ли последний прочитанный столбец значение SQL NULL». .

https://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html

И не был ли пустой набор результатов (что я ранее думал

По доперли это я изменил метод nullSafeGet от:

@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 Object nullSafeGet(ResultSet _rs, String[] _names, SessionImplementor _sessionImplementor, Object _owner) throws HibernateException, SQLException { 

     Object result = null; 
     Short shortId = StandardBasicTypes.SHORT.nullSafeGet(_rs, _names[0], _sessionImplementor); 

     if (shortId != null) { 
     log.debug("setting: " + _names[0] + " : " + _rs.wasNull() + " : " + _owner); 
     Long enumId = shortId.longValue(); 
     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); 
     } 
     } else { 
     result = null; 
     } 

     return result; 
    } 

А потом это сработало.

Смежные вопросы