2012-02-12 34 views
0

我正在使用hibernate框架來使用Oracle或Sybase(客戶選擇)。但是當我們將連接切換到Sybase時,我遇到了一些關於多對一約束的問題。首先,Oracle抱怨在hibernate_hbm.xml中定義爲「文本」的clob字段,我用自定義類型中的二進制(ClobTypeDescriptor.STREAM_BINDING)解決了這個問題。對於甲骨文來說,一切都很正常,而且完美。但是,當我將數據庫服務器切換到Sybase時,在嘗試保存具有外鍵約束的表上的記錄時出現以下錯誤。hibernate - 多對一約束中不支持的SQL類型2005

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屬性,使用數字(19,0)字段爲id列創建表。發生這種情況時,我們的映射會被拋出錯誤。

我讀了一些文章,我測試了它們,但沒有成功。這是我的測試。


將映射添加到not-null =「true」<many-to-one name="classA_Data" class="classA" column="tableA_Id" />行。 FAILED

hibernate.max_fetch_depth = 1添加到屬性。失敗。

hibernate.jdbc.use_get_generated_keys=true添加到屬性。失敗。

這些都發生在Sybase方面。

我測試了jConnect的6.0(JDBC3)和7.0(jdbc4)

我使用Hibernate 3.6.1決賽。 使用Oracle11gR2和Sybase測試12.0.5 - 15.0.2 - 15.0.3

有什麼建議嗎?

+0

'<多對一名=「classA_Data」sqltype =「bigint」>'? – Firo 2012-02-14 12:45:51

回答

0

我已經想出了什麼是實際問題並解決了它。我們對oracle實例使用clob字段的自定義類型(這是oracle的另一個解決方案),但是當我們實現這個自定義類型時,sybase實例開始拋出異常。一開始,我認爲問題是制約因素,但根本不是。問題是;試圖設置null爲clob字段爲sybase clob類型。我在我們的自定義類型類上實現了overrided nullSafeSet方法,就好像對於自定義類型的值爲空,將類型轉換爲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); 
    } 
}