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 を使用し、JPA プロバイダーとして Hibernate 3.5.0-Final を使用しています。hsqldb の Hibernate 方言は次のとおりです。

<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 = VARBINARYcol.getSqlType( dialect, mapping )が呼び出されて col.sqlType を初期化すると、何らかの理由で blob(255) が取得されます。休止状態構成で hsqldb 方言を更新する必要があると思います。しかし、よくわかりません。問題を解決するために何をすべきかわかりません。

4

2 に答える 2

2

Liquibase は、バージョン 2.0 以降の hsqldb で利用可能になった BLOB に SQL BLOB 型を使用しません。hsqldb 1.8.X では、blob に使用された sql 型は varbinary でした。この問題を解決するために、休止状態で使用される 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 は現在のものを更新するか、HsqlTypeConverterhsqldb 2.X バージョンをサポートする新しいものを追加する必要があると思います。

于 2013-06-04T11:27:36.327 に答える
2

アノテーションのプロパティの255デフォルト値であるため、検証クエリを取得しています。length@Column

HSQLDB はVARBINARYBLOB SQL 型の両方をサポートしているため、 Hibernate は列BLOBのデフォルトの SQL マッピングとして使用しているようです。byte[]

次のプロパティをVARBINARY指定することで、 Hibernate に明示的に使用するように指示できます。columnDefinition@Column

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

hereで説明されているように、列の定義はその長さを明示的に指定することで変更される場合がありますが、通常はString列に関連しています。

于 2013-06-03T10:21:40.910 に答える