2

我收到以下错误:

Caused by: org.hibernate.HibernateException: Wrong column type in PUBLIC.PUBLIC.ALL_TYPES_ENTITIES for column blob1. Found: varbinary, expected: blob(255)
    at org.hibernate.mapping.Table.validateColumns(Table.java:383)

我正在使用 liquibase 创建表:

        <column name="blob1" type="BLOB">
            <constraints nullable="true"/>
        </column>

java实体有一个字段:

private byte[] blob1;
...
@Basic(fetch = FetchType.LAZY)
@Lob
@Column(name = "blob1")
public byte[] getBlob1() {
    return blob1;
}

我使用 hsqldb 2.2.9 作为数据库,使用 Hibernate 3.5.0-Final 作为 JPA 提供程序。hsqldb 的休眠方言是:

<prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>

当 liquibase 生成表时,liquibase HsqlTypeConverter 应该使用 VARBINARY 作为 sql 类型。当 Hibernate 验证方案时,它认为类型是 blob(255),将其与 VARBINARY 进行比较并抛出异常。

这是验证表的代码:

public void validateColumns(Dialect dialect, Mapping mapping, TableMetadata tableInfo) {
    Iterator iter = getColumnIterator();
    while ( iter.hasNext() ) {
        Column col = (Column) iter.next();

        ColumnMetadata columnInfo = tableInfo.getColumnMetadata( col.getName() );

        if ( columnInfo == null ) {
            throw new HibernateException( "Missing column: " + col.getName() + " in " + Table.qualify( tableInfo.getCatalog(), tableInfo.getSchema(), tableInfo.getName()));
        }
        else {
            final boolean typesMatch = col.getSqlType( dialect, mapping ).toLowerCase()
                    .startsWith( columnInfo.getTypeName().toLowerCase() )
                    || columnInfo.getTypeCode() == col.getSqlTypeCode( mapping );
            if ( !typesMatch ) {
                throw new HibernateException(
...

在调试器中,我可以看到何时抛出异常,即col.sqlType = blob(255), columnInfo.typeName = VARBINARY. 出于某种原因,当col.getSqlType( dialect, mapping )调用 init col.sqlType 时,它​​会得到 blob(255)。我想我应该在休眠配置中更新 hsqldb 方言。但不确定。不知道我该怎么做才能解决问题。

4

2 回答 2

2

您正在进入255验证查询,因为它是注释length属性的默认值。@Column

由于 HSQLDB 支持SQLVARBINARYBLOB SQL 类型,显然 Hibernate 将BLOB其用作byte[]列的默认 SQL 映射。

VARBINARY您可以通过指定以下columnDefinition属性来明确告诉 Hibernate 使用@Column

@Basic(fetch = FetchType.LAZY)
@Lob
@Column(name = "blob1", columnDefinition = "VARBINARY")
public byte[] getBlob1() {
    return blob1;
}

请注意,列定义可以通过明确指定其长度来更改,如此处所述但通常与String列相关。

于 2013-06-03T10:21:40.910 回答
2

Liquibase 不使用 sql BLOB 类型作为自 2.0 版本以来在 hsqldb 中可用的 blob。在 hsqldb 1.8.X 中,用于 blob 的 sql 类型是:varbinary。为了解决这个问题,我更新了 hibernate 中使用的 hsqldb 方言:

public class HSQL_1_8_X_Dialect extends HSQLDialect {

    public HSQL_1_8_X_Dialect() {
        super();

        registerColumnType(Types.BLOB, "varbinary");
        registerColumnType(Types.CLOB, "varchar");
    }
}

<property name="hibernate.dialect" value="com.savdev.datasource.dialect.HSQL_1_8_X_Dialect"/>

它解决了这个问题。另外,我认为 liquibase 应该更新当前HsqlTypeConverter版本或添加支持 hsqldb 2.X 版本的新版本。

于 2013-06-04T11:27:36.327 回答