Hibernate / hsqldb 2 не может гидрировать колонку BLOB-объектов - PullRequest
3 голосов
/ 17 февраля 2011

Я пытаюсь загрузить объект с байтовыми данными (помеченными @Lob) из базы данных HSQL 2.0 с использованием Hibernate 3.5.6.Эта сущность может быть сохранена без каких-либо проблем и загружается нормально, если она находится в кеше (т.е. не нуждается в гидратации).Тем не менее, когда объект не находится в кэше (требуется его гидратация), я получаю следующее исключение:

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?

1 Ответ

3 голосов
/ 17 февраля 2011

Я нашел проблему в методе getBytes в JDBCResultSet.java (HSQLDB 2.0.0, скачанный из проекта Sourceforge). HSQLDB 2.0 поддерживает столбец BLOB-объектов, а 1.8. * Нет, поэтому это может быть ошибкой, если они не полностью обновили свою реализацию JDBC. Следующий патч для метода getBytes решает проблему:

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();
}

Первоначальный метод был:

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

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

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

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