2011-02-17 45 views
3

我想從使用Hibernate 3.5.6的HSQL 2.0數據庫加載一個字節數據(用@Lob註釋)的實體。這個實體能夠被保存而沒有任何問題,並且如果它在緩存中(即,不需要被水合)就可以被正確加載。然而,當實體不在緩存中(需要被水合),我收到以下異常:休眠/ hsqldb 2無法水合Blob列

Caused by: org.hsqldb.HsqlException: incompatible data type in conversion: from SQL type BLOB to [B, value: instance of org.hsqldb.types.BlobDataID 
    at org.hsqldb.error.Error.error(Unknown Source) 
    ... 68 more 

以下是完整的堆棧跟蹤(減去一些特定領域的痕跡)的詳細背景:

javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not execute query 
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1235) 
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1168) 
... 

Caused by: org.hibernate.exception.SQLGrammarException: could not execute query 
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:92) 
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66) 
at org.hibernate.loader.Loader.doList(Loader.java:2452) 
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2192) 
at org.hibernate.loader.Loader.list(Loader.java:2187) 
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:452) 
at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:363) 
at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:196) 
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1258) 
at org.hibernate.impl.QueryImpl.list(QueryImpl.java:102) 
at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:241) 
... 45 more 

Caused by: java.sql.SQLSyntaxErrorException: incompatible data type in conversion: from SQL type BLOB to [B, value: instance of org.hsqldb.types.BlobDataID 
at org.hsqldb.jdbc.Util.sqlException(Unknown Source) 
at org.hsqldb.jdbc.Util.throwError(Unknown Source) 
at org.hsqldb.jdbc.JDBCResultSet.getColumnInType(Unknown Source) 
at org.hsqldb.jdbc.JDBCResultSet.getBytes(Unknown Source) 
at org.hsqldb.jdbc.JDBCResultSet.getBytes(Unknown Source) 
at org.hibernate.type.AbstractBynaryType.get(AbstractBynaryType.java:103) 
at org.hibernate.type.NullableType.nullSafeGet(NullableType.java:186) 
at org.hibernate.type.NullableType.nullSafeGet(NullableType.java:175) 
at org.hibernate.type.AbstractType.hydrate(AbstractType.java:105) 
at org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:2267) 
at org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1443) 
at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1371) 
at org.hibernate.loader.Loader.getRow(Loader.java:1271) 
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:619) 
at org.hibernate.loader.Loader.doQuery(Loader.java:745) 
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:270) 
at org.hibernate.loader.Loader.doList(Loader.java:2449) 
... 53 more 
Caused by: org.hsqldb.HsqlException: incompatible data type in conversion: from SQL type BLOB to [B, value: instance of org.hsqldb.types.BlobDataID 
at org.hsqldb.error.Error.error(Unknown Source) 
... 68 more 

當我使用Hibernate 3.5.6和HSQL 1.8.0.10時,可能因爲使用了不同的方言(Blob列在HSQL 1.8中不受支持)而沒有發生此問題。我正在使用的Hibernate版本應該支持HSQL 2,並且我已檢查它是否正確檢測到HSQL版本並使用正確的方言。當我使用MySQL時,這個問題也不會發生。

有問題的實體已被設置LOB列了,像這樣:

@Entity 
public class ImageEntity extends IdEntity { 

    @Lob 
    @Column(name="IMAGE") 
    private byte[] imageBytes; 
    ... 

這是一個Hibernate/HSQL 2.0的bug?

回答

3

我在JDBCResultSet.java(從Sourceforge項目下載的HSQLDB 2.0.0)getBytes方法中發現問題。 HSQLDB 2.0支持1.8 *不包含的blob列,所以它可能是一個沒有完全更新其JDBC實現的bug。以下補丁的getBytes方法解決了這個問題:

原始的方法是:

public byte[] getBytes(int columnIndex) throws SQLException { 

    Object x = getColumnInType(columnIndex, Type.SQL_VARBINARY); 

    if (x == null) { 
     return null; 
    } 

    return ((BinaryData) x).getBytes(); 
} 
+0

感謝您報告這一點。現在可以在http://hsqldb.org/support上找到2.0.1的快照jar並修復。 – fredt 2011-02-18 00:30:33