hibernate - 在多对一约束上不受支持的 SQL 类型 2005
Posted
技术标签:
【中文标题】hibernate - 在多对一约束上不受支持的 SQL 类型 2005【英文标题】:hibernate - Unsupported SQL type 2005 on many-to-one constraint 【发布时间】:2012-02-12 18:31:03 【问题描述】:我使用休眠框架能够使用 Oracle 或 Sybase(客户选择)。但是当我们切换到 Sybase 的连接时,我遇到了一些关于多对一约束的问题。首先,Oracle 抱怨在 hibernate_hbm.xml 中定义为“文本”的 clob 字段,我通过在自定义类型中使用二进制 (ClobTypeDescriptor.STREAM_BINDING
) 解决了这个问题。对于甲骨文来说,一切正常,运行完美。但是当我将数据库服务器切换到 Sybase 时,尝试在具有外键约束的表上保存记录时出现以下错误。
Caused by: java.sql.SQLException: JZ006: Caught IOException: java.io.IOException: JZ0SL: Unsupported SQL type 2005.
at com.sybase.jdbc4.jdbc.SybConnection.getAllExceptions(Unknown Source)
at com.sybase.jdbc4.jdbc.SybStatement.handleSQLE(Unknown Source)
at com.sybase.jdbc4.jdbc.SybStatement.sendQuery(Unknown Source)
at com.sybase.jdbc4.jdbc.SybPreparedStatement.sendQuery(Unknown Source)
at com.sybase.jdbc4.jdbc.SybStatement.executeUpdate(Unknown Source)
at com.sybase.jdbc4.jdbc.SybPreparedStatement.executeUpdate(Unknown Source)
at org.hibernate.id.IdentityGenerator$GetGeneratedKeysDelegate.executeAndExtract(IdentityGenerator.java:94)
at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:57)
... 47 more
这是映射:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.aykut.test.persistence">
<class name="classA" table="tableA">
<id name="tableA_Id" type="long">
<generator class="native" />
</id>
<property name="someDateColumn" type="timestamp" />
<set name="destinations" table="tableB" cascade="all" lazy="false">
<key column="tableA_Id" />
<one-to-many class="classB" />
</set>
</class>
<class name="classB" table="tableB">
<id name="tableB_Id" type="long">
<generator class="native" />
</id>
<many-to-one name="classA_Data" class="classA" column="tableA_Id" lazy="false" />
<property name="someInfoColumn" length="64" not-null="true" type="string" />
</class>
</hibernate-mapping>
我进行了一些测试,如果这两个表之间没有任何关系,则可以正常保存记录。
我觉得有些奇怪,如果我使用 ddl 手动创建表并将 bigint
类型赋予 id 列,并且如果我不使用 hibernate.hbm2ddl.auto=update
属性,一切看起来都很正常。以 bigint 类型创建的列并且工作正常。
如果我使用 hibernate.hbm2ddl.auto=update
属性,则使用 id 列的 numeric(19,0) 字段创建的表。发生这种情况时,我们的映射会抛出错误。
我阅读了一些文章并对其进行了测试,但没有成功。这是我的测试。
将映射添加到 not-null="true" <many-to-one name="classA_Data" class="classA" column="tableA_Id" />
行。失败
将hibernate.max_fetch_depth = 1
添加到属性。失败。
将hibernate.jdbc.use_get_generated_keys=true
添加到属性。失败。
这些都发生在 Sybase 方面。
我测试了 jconnect 6.0(jdbc3) 和 7.0 (jdbc4)
我使用的是休眠 3.6.1 最终版本。 使用 Oracle11gR2 和 Sybase 12.0.5 - 15.0.2 - 15.0.3 测试
有什么建议吗?
【问题讨论】:
<many-to-one name="classA_Data" sqltype="bigint">
?
【参考方案1】:
我已经弄清楚了实际问题并解决了它。我们为 oracle 实例的 clob 字段使用自定义类型。(这是 oracle 的另一种解决方案。)但是当我们实现此自定义类型时,sybase 实例开始抛出上述异常。一开始,我认为问题是约束,但根本不是。问题是;尝试为 sybase clob 类型的 clob 字段设置 null。我在自定义类型类上实现了覆盖的 nullSafeSet 方法,就好像自定义类型的值为 null 一样,将类型转换为 varchar。我们还必须为 sybase clob 字段创建新的 texttypedescriptor。然后它工作。这是解决方案:
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Types;
import org.hibernate.HibernateException;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.type.AbstractStandardBasicType;
import org.hibernate.type.descriptor.java.StringTypeDescriptor;
import org.hibernate.type.descriptor.sql.ClobTypeDescriptor;
public class TextType extends AbstractStandardBasicType<String>
public static final TextType INSTANCE = new TextType();
public TextType()
super((myapp.isOracle?ClobTypeDescriptor.STREAM_BINDING:CustomSybaseTextTypeDescriptor.INSTANCE), StringTypeDescriptor.INSTANCE);
public String getName()
return "customtext";
@Override
public void nullSafeSet(PreparedStatement arg0, Object arg1, int arg2,
boolean[] arg3, SessionImplementor arg4)
throws HibernateException, SQLException
if(arg1 == null)
arg0.setNull(arg2,Types.VARCHAR);
else
super.nullSafeSet(arg0, arg1, arg2, arg4);
【讨论】:
以上是关于hibernate - 在多对一约束上不受支持的 SQL 类型 2005的主要内容,如果未能解决你的问题,请参考以下文章