2016-11-21 2 views
0

Я неудачный разработчик, который должен работать с очень старой базой данных. Проблема заключается в том, что база данных содержит пользовательские типы данных:Hibernate JPA DB2 Custom Data Type

CREATE DISTINCT TYPE SCHEMA.T_STUPID_ID AS 
    SMALLINT WITH COMPARISONS 
; 

Так что я не могу изменить, но нужно, чтобы получить данные и запросить его. Оказывается, что это не работает, вызывает при запросе от Id (findOne) с использованием JPA пружинные данных (хранилища), я получаю следующее сообщение об ошибке:

DB2 SQL Error: SQLCODE=-401, SQLSTATE=42818, SQLERRMC==, DRIVER=4.19.26 

, который: данные ВИДЫ Операндов РАБОТЫ НЕ СОВМЕСТИМОСТЬ Так это звучит как запросы не работают с пользовательскими типами:/

Я также пробовал так:

@Query("select p from ImSickOfThisEntity p where cast(p.entityId as integer) 
= ?1 ") 

Но я получил:

DB2 SQL Error: SQLCODE=-461, SQLSTATE=42846, SQLERRMC=IPSDBO.T_PRODUCT_ID;SYSIBM.INTEGER 

, который переводит:

A VALUE WITH DATA TYPE source-data-type CANNOT BE CAST TO TYPE target-data-type 

Как бороться с такими пользовательскими типами? Google не помогает, я могу найти только пользовательские типы Java со стандартными типами столбцов базы данных ....

ответ

0

Вам нужно будет реализовать UserType, и вы можете указать sqlTypes.

public class SmallIntHibernateType implements UserType { 

@Override 
public int[] sqlTypes() { 
    return new int[] {Types.SMALLINT}; 
} 

@Override 
public Class returnedClass() { 
    return Integer.class; 
} 

@Override 
public boolean equals(Object o, Object o2) throws HibernateException { 
    if (o == null && o2 == null) { 
     return true; 
    } else if (o == null) { 
     return false; 
    } else if (o2 == null) { 
     return false; 
    } else { 
     return ((Integer) o).intValue() == ((Integer) o2).intValue(); 
    } 
} 

@Override 
public int hashCode(Object o) throws HibernateException { 
    return o.hashCode(); 
} 

@Override 
public Object nullSafeGet(ResultSet resultSet, String[] strings, SharedSessionContractImplementor sessionImplementor, Object o) throws HibernateException, SQLException { 
    return resultSet.getInt(strings[0]); 
} 

@Override 
public void nullSafeSet(PreparedStatement preparedStatement, Object value, int index, SharedSessionContractImplementor sessionImplementor) throws HibernateException, SQLException { 
    if (value == null || value.equals(0)) { 
     preparedStatement.setNull(index, Types.INTEGER); 
     return; 
    } 

    if (!(value instanceof Integer)) { 
     throw new UnsupportedOperationException("can't convert " + value.getClass()); 
    } 

    preparedStatement.setInt(index, ((Integer) value)); 
} 

@Override 
public Object deepCopy(Object value) throws HibernateException { 
    if (value == null) { 
     return null; 
    } 

    if (!(value instanceof Integer)) { 
     throw new UnsupportedOperationException("can't convert " + value.getClass()); 
    } 

    return value; 
} 

@Override 
public boolean isMutable() { 
    return false; 
} 

@Override 
public Serializable disassemble(Object value) throws HibernateException { 
    if (!(value instanceof Integer)) { 
     throw new UnsupportedOperationException("can't convert " + value.getClass()); 
    } 

    return (Integer) value; 
} 

@Override 
public Object assemble(Serializable cached, Object owner) throws HibernateException { 
    if (!(cached instanceof Integer)) { 
     throw new UnsupportedOperationException("can't convert " + cached.getClass()); 
    } 

    return cached; 
} 

@Override 
public Object replace(Object original, Object target, Object owner) throws HibernateException { 
    return original; 
} 
} 

Затем на вашей сущности вам необходимо указать тип.

+0

Так что, если я использую аннотацию @Type, в чем цель SmallIntHibernateType? Является ли это параметром where where в репозитории spring-data-jpa? – maslan

+0

Класс SmallIntHybernateType - это то, что на самом деле делает работа по сговору спящего, что SQL-тип столбца и обработать, чтобы преобразовать его в ваш тип Java. Аннотирование @Type - это то, что указывает на спящий режим для поиска вашего настраиваемого типа столбца. – Mamof

+0

нормально, это не сработало, даже без этого нет проблем с извлечением данных. Проблема с запросами - предложение where не работает, поскольку DB2 утверждает, что это плохой тип. Единственное решение, с которым я пришел, - это родной запрос с приложением в хранилище SpringDataJPA – maslan