我收到以下错误:
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的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 = VARBINARY
。出于某种原因,当对{init} col.sqlType调用col.getSqlType( dialect, mapping )
时,它会获得blob(255)。
我想我应该在hibernate配置中更新hsqldb dialect。但不确定。
不知道我该怎么做才能解决问题。
答案 0 :(得分: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版本的新版本。
答案 1 :(得分:1)
您在验证查询中收到255
,因为它是length
注释的@Column
属性的默认值。
由于HSQLDB同时支持VARBINARY
和BLOB
SQL types,显然Hibernate使用BLOB
作为byte[]
列的默认SQL映射。
您可以通过指定VARBINARY
的{{1}}属性明确告诉Hibernate使用columnDefinition
:
@Column
请注意,列定义可以通过明确指定其长度来更改,如here所述,但通常与@Basic(fetch = FetchType.LAZY)
@Lob
@Column(name = "blob1", columnDefinition = "VARBINARY")
public byte[] getBlob1() {
return blob1;
}
列相关。