2012-02-12 8 views
0

でサポートされていないSQLタイプ2005を、私はOracleやSybaseの(顧客の選択)を使用できるようにするフレームワークを休止状態使用しています。しかし、Sybaseとの接続を切り替えると、多対1の制約についていくつか問題があります。最初に、Oracleはhibernate_hbm.xmlで "text"と定義されていたclobフィールドについて苦情を申し立てました。この問題をカスタムタイプでバイナリ(ClobTypeDescriptor.STREAM_BINDING)を使用して解決しました。 Oracleの場合、すべて正常であり、完璧に機能します。しかし、DBサーバーを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> 

私はいくつかのテストを実行して、この2つのテーブル間には何らかの関係が存在しない場合、レコードが正常に保存することができます。

手動でddlを使用してテーブルを作成し、idカラムにbigintタイプを指定して、hibernate.hbm2ddl.auto=updateプロパティを使用しないと、すべてが正常に見えます。 bigint型で作成され、正常に動作する列。

私はhibernate.hbm2ddl.auto=updateプロパティを使用する場合は、ID列の数値(19,0)フィールドで作成した表。これが起こると、私たちのマッピングはエラーの上でスローされます。

私はいくつかの記事を読み、テストしますが、成功はありません。ここに私のテストがあります。


ないヌル= "true" を<many-to-one name="classA_Data" class="classA" column="tableA_Id" />行へのマッピングを追加します。プロパティにhibernate.max_fetch_depth = 1を追加

に失敗しました。 FAILED。

プロパティにhibernate.jdbc.use_get_generated_keys=trueを追加します。 FAILED。

これらはすべてSybase側で発生します。

私は3.6.1最終的に休止状態使用していますのjConnect 6.0(JDBC3)および7.0(jdbc4)

の両方をテストしました。 Oracle11gR2およびSybase 12.0.5でテスト - 15.0.2 - 15.0.3

どれ提案してください?

+0

''? – Firo

答えて

0

私は、実際の問題だったものを考え出し、それを解決しました。 oracleインスタンスのclobフィールドにはカスタム・タイプを使用します(これはoracleの別のソリューションです)。しかし、このカスタム・タイプを実装すると、sybaseインスタンスは例外をスローするようになりました。最初は、問題は制約だと思ったが、まったく問題ではないと思った。問題はあった。 sybase clob型のフィールドをクローブするためにnullを設定しようとしています。カスタム型のnullSafeSetメソッドを実装しました。たとえば、valueが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); 
    } 
}