本文介绍了休眠/ hsqldb 2无法水合Blob列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用Hibernate 3.5.6从HSQL 2.0数据库加载一个带有字节数据(用@Lob注释)的实体。这个实体能够被保存而没有任何问题,并且如果它在缓存中(即,不需要被水合)就可以被正确加载。但是,当实体不在缓存中(需要水合)时,我收到以下异常:

 由于: org.hsqldb.HsqlException:转换中的不兼容数据类型:从SQL BLOB类型到[B,值:org.hsqldb.types.BlobDataID实例。org.hsqldb.error.Error.error(Unknown Source)中的

... 68 more

以下是完整的堆栈跟踪(减去某些特定于域的跟踪) for more context:

  javax.persistence.PersistenceException:org.hibernate.exception.SQLGrammarException:无法执行查询
在org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1235)
在org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1168)


导致:org.hibernate.exception.SQLGrammarException:无法执行查询
在org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:92)
在org。 hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
在org.hibernate.loader.Loader.doList(Loader.java:2452)
在org.hibernate.loader.Loader.listIgnoreQueryCache( Loader.java:2192)
在org.hibernate.loader.Loader.list(Loader.java:2187)
在org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:452)在org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:363)

在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

导致:java.sql.SQLSyntaxErrorException:转换中的不兼容数据类型:从SQL BLOB类型到[B,value :org.hsqldb.types.BlobDataID实例org.hsqldb.jdbc.Util.sqlException(未知源)
org.hsqldb.jdbc.Util.throwError(未知来源)
在org.hsqldb.jdbc.JDBCResultSet.getColumnInType(来源不明)
在org.hsqldb.jdbc.JDBCResultSet.getBytes(来源不明)
在org.hsqldb.jdbc.JDBCResultSet .getBytes(来源不明)
在org.hibernate.type.AbstractBynaryType.get(AbstractBynaryType.java:103)
在org.hibernate.type.NullableType.nullSafeGet(NullableType.java:186)
在org.hibernate.type.NullableType.nullSafeGet(NullableType.java:175)
在org.hibernate.type.AbstractType.hydrate(AbstractType.java:105)
在org.hibernate.persister .entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:2267)
在org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1443)
在org.hibernate.loader.Loader.instanceNotYetLoaded(装载机.java:1371)
at org.hibernate.loader.Loader.getRow(Loader.java:1271)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:619)
在org.hibernate.loader.Loader.doQuery(Loader.java:745)
在org.hibernate.loader.Loader.doQueryAndI nitializeNonLazyCollections(Loader.java:270)
at org.hibernate.loader.Loader.doList(Loader.java:2449)
... 53 more
引起:org.hsqldb.HsqlException :在转换中不兼容的数据类型:从SQL类型BLOB到[B,值:org.hsqldb.types.BlobDataID的实例
在org.hsqldb.error.Error.error(未知源)
.. 。68 more

当我使用Hibernate 3.5.6和HSQL 1.8.0.10时,可能是因为使用了不同的方言(在HSQL 1.8中不支持Blob列)。我正在使用的Hibernate版本应该支持HSQL 2,并且我已检查它是否正确检测到HSQL版本并使用正确的方言。这个问题在我使用MySQL时也不会发生。



有问题的实体有一个Lob列,它的设置如下所示:

  @Entity 
public class ImageEntity extends IdEntity {

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

这是Hibernate / HSQL 2.0的bug吗?

解决方案

我在JDBCResultSet.java(从Sourceforge项目下载的HSQLDB 2.0.0)getBytes方法中发现了问题。 HSQLDB 2.0支持1.8 *不包含的blob列,所以它可能是一个没有完全更新其JDBC实现的bug。下面的getBytes方法的补丁解决了这个问题:

pre $ public $ byte getBytes(int columnIndex)throws SQLException {

类型sourceType = resultMetaData.columnTypes [columnIndex-1];
if(sourceType.isLobType()){
Blob b = getBlob(columnIndex);
return b.getBytes(1,(int)b.length());
}

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

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

return((BinaryData)x).getBytes();

$ / code>

原始方法是:

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

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

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

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


I am trying to load an entity with byte data (annotated with @Lob) from an HSQL 2.0 database using Hibernate 3.5.6. This entity is able to be saved without any problems and is loaded fine if it is in the cache (i.e. does not need to be hydrated). However, when the entity is not in the cache (needs to be hydrated), I receive the following exception:

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

Here is the full stack trace (minus some domain specific trace) for more context:

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

This problem did not occur when I used Hibernate 3.5.6 and HSQL 1.8.0.10, probably because of the different dialect used (Blob column wasn't supported in HSQL 1.8). The version of Hibernate that I'm using is supposed to support HSQL 2 and I have checked that it is properly detecting the HSQL version and using the correct dialect. This problem also does not occur when I use MySQL.

The entity in question has a Lob column which is set up like so:

@Entity
public class ImageEntity extends IdEntity {

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

Is this a Hibernate/HSQL 2.0 bug?

解决方案

I found the problem in JDBCResultSet.java (HSQLDB 2.0.0 downloaded from Sourceforge project) getBytes method. HSQLDB 2.0 supports a blob column where 1.8.* doesn't, so it might be a bug where they haven't fully updated their JDBC implementation. The following patch to the getBytes method solves the problem:

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

    Type sourceType = resultMetaData.columnTypes[columnIndex-1];
    if (sourceType.isLobType()){
        Blob b = getBlob(columnIndex);
        return b.getBytes(1, (int)b.length());
    }

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

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

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

Original method was:

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

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

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

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

这篇关于休眠/ hsqldb 2无法水合Blob列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-18 22:07