2016-11-21 169 views
0

我是一位不幸的開發人員,需要使用非常遺留的數據庫。問題是,該數據庫包含自定義數據類型:Hibernate JPA DB2自定義數據類型

CREATE DISTINCT TYPE SCHEMA.T_STUPID_ID AS 
    SMALLINT WITH COMPARISONS 
; 

所以我不能改變的,但需要得到的數據和查詢。

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

是:一個操作的操作數的數據類型並不看來,這是行不通的,使用彈簧數據JPA(資料庫),我收到以下錯誤引起的ID(findOne)查詢時兼容 所以它聽起來像查詢不使用自定義類型的工作:/

我也試過這樣:

@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 

如何處理這樣的自定義類型?谷歌沒有幫助,我只能找到具有標準數據庫列類型的自定義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; 
} 
} 

然後在你的實體上,你需要指定使用的類型。

@Id 
@Type(type = "com.data.system.SmallIntHibernateType") 
private int id; 
+0

因此,如果我使用@Type註釋,SmallIntHibernateType的目的是什麼?它是spring-data-jpa存儲庫中的where子句參數嗎? – maslan

+0

SmallIntHybernateType類實際上是告訴hibernate該列是什麼SQL類型並將其轉換爲Java類型的工作。 @Type註釋是hibernate查找自定義列類型的要點。 – Mamof

+0

好吧,那沒用,即使沒有這個,數據檢索也沒有問題。查詢存在問題 - where子句不起作用,因爲DB2聲明它是一種錯誤的類型。我使用的唯一解決方案是在SpringDataJPA存儲庫中使用強制轉換的本地查詢 – maslan