简体   繁体   English

休眠-多对一约束不受支持的SQL类型2005

[英]hibernate - Unsupported SQL type 2005 on many-to-one constraint

I am using hibernate framework to be able to use Oracle or Sybase (customer choice). 我正在使用hibernate框架以能够使用Oracle或Sybase(客户选择)。 But when we switch the connection to Sybase, I have some issues about many-to-one constraint. 但是,当我们将连接切换到Sybase时,我遇到了一些关于多对一约束的问题。 First of all, Oracle complained for clob fields which have been defined as "text" in hibernate_hbm.xml and I solved this issue with using binary ( ClobTypeDescriptor.STREAM_BINDING ) in custom type. 首先,Oracle抱怨在hibernate_hbm.xml中将clob字段定义为“文本”,我通过在自定义类型中使用二进制( ClobTypeDescriptor.STREAM_BINDING )解决了此问题。 For Oracle, everything is normal and works perfect. 对于Oracle,一切正常且完美。 But when I switch the db server to Sybase, I get the following error when trying to save record(s) on table which have foreign key constraint. 但是,当我将数据库服务器切换到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

Here is the mapping: 这是映射:

<?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>

I run some tests and if there is no any relation between these two tables, records can be saved normally. 我进行了一些测试,如果这两个表之间没有任何关系,则可以正常保存记录。

There is some weirdness to me like, if I create tables with ddl manually and give bigint type to id columns and if I don't use hibernate.hbm2ddl.auto=update property, everything looks normal. 我有些奇怪,例如,如果我手动创建带有ddl的表并将bigint类型赋予id列,并且如果我不使用hibernate.hbm2ddl.auto=update属性,那么一切看起来都很正常。 Columns created in bigint type and works fine. 以bigint类型创建的列可以正常工作。

if I use hibernate.hbm2ddl.auto=update property, tables created with numeric(19,0) fields for id columns. 如果我使用hibernate.hbm2ddl.auto=update属性,则为id列使用numeric(19,0)字段创建的表。 When this happen, our mapping is thrown above error. 发生这种情况时,我们的映射将抛出错误。

I read some article and I test them but there is no success. 我读了一些文章并对其进行了测试,但没有成功。 Here is my tests. 这是我的测试。


Adding mapping to not-null="true" <many-to-one name="classA_Data" class="classA" column="tableA_Id" /> row. 将映射添加到not-null =“ true” <many-to-one name="classA_Data" class="classA" column="tableA_Id" />行中。 FAILED 失败

Adding hibernate.max_fetch_depth = 1 to properties. hibernate.max_fetch_depth = 1添加到属性。 FAILED. 失败。

Adding hibernate.jdbc.use_get_generated_keys=true to properties. hibernate.jdbc.use_get_generated_keys=true添加到属性。 FAILED. 失败。

These all are happens for Sybase side. 这些都是在Sybase方面发生的。

I tested both jconnect 6.0(jdbc3) and 7.0 (jdbc4) 我同时测试了jconnect 6.0(jdbc3)和7.0(jdbc4)

I am using hibernate 3.6.1 final. 我正在使用休眠3.6.1最终版。 Tested with Oracle11gR2 and Sybase 12.0.5 - 15.0.2 - 15.0.3 经过Oracle11gR2和Sybase 12.0.5-15.0.2-15.0.3的测试

Any suggestion please? 有什么建议吗?

I have figured out what was the actual problem and solved it. 我已经弄清楚了实际的问题并解决了。 We use custom type for clob field for oracle instances.(This was another solution for oracle.) but when we implemented this custom type, sybase instances started to throw above exception. 我们将自定义类型用于oracle实例的clob字段。(这是oracle的另一种解决方案。)但是,当实现此自定义类型时,sybase实例开始抛出上述异常。 At the beginning, I thought the problem is constraints but not at all. 一开始,我认为问题是约束,而不是根本。 Problem was; 问题是; trying to set null to clob fields for sybase clob type.I implemented the overrided nullSafeSet method on our custom type class as if value is null for custom type, convert type to varchar. 试图为sybase clob类型的clob字段设置null。我在自定义类型类上实现了重写的nullSafeSet方法,就好像自定义类型的value为null一样,将类型转换为varchar。 Also we have had to create new texttypedescriptor for sybase clob fields. 另外,我们还必须为sybase clob字段创建新的texttypedescriptor。 Then it works. 然后就可以了。 Here is the solution: 解决方法如下:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM