2009-03-06 42 views
3

私はOracle 10gとHibernate 2.1(古いバージョンですが、修正するためにアップグレードすることはできません)を使用しています。私はTIN、varchar2(9)という名前のnullableではない列を持つテーブルを持っています。この列は、フラットファイルからロードされたデータをステージングするために使用されるため、9つのスペース(入力ファイルに9つのスペースがある場合は '')を含む長さ9の任意の文字列を格納できます。Hibernateが文字列をトリミングしないようにするにはどうすればよいですか?

  1. のOracle 10gは自動的にNULLに空の文字列を変換します

    は私が気づいたことはということです。したがって、実行すると:

    SELECT NVL('', 'Input string converted to NULL') FROM dual; 
    

    結果は「入力文字列はNULLに変換されました」ではなく「」です。私はこれが問題に関連していると思う。

  2. TIN値が9文字(または任意の数のスペース)で、他の文字がないレコードをHibernateが読み込むと、その値がメモリに ''として格納されます。 Hibernateはその後、値が9つの空白から空の文字列に変更されたと考えるようになりました。レコードがデータベースに書き戻された場合、Hibernateは空白文字列を9文字ではなく空文字列に書き出しようとし、Oracleは明らかにこれをnullに変換してからnull以外の制約違反をスローします。参考のため

、ここHBMは、このコラムのためです:

<property 
    name="tin" 
    type="java.lang.String" 
    column="TIN" 
    not-null="true" 
    length="9"> 

私の質問は、どのように私は、文字列のみを空にスペースを含む値を変換しないで休止状態指示していますか?

更新1:私は戻って 'text'のような文字列をテストしただけで、Hibernateはこれらのスペースもトリミングし、文字列 'text'を作り、値が変更されたと考えてしまうことに気付きました。私は何かを欠いているに違いない。これはデフォルトの動作のようには見えません。

アップデート2:これは、JavaソースへのHBMは、文字列のトリムの源であるかもしれない変換hbm2java Antタスクのように見えます。まだ調査中。

おかげで、 ジェフ

編集:変更された質問の文言は、より正確に。

答えて

3

この問題は、Hibernateでは問題ではないことが明らかになりました。私が取り組んでいるプロジェクトは、hbm2java Antタスクを使ってHBMファイルからJava POJOを生成するように設定されていました。次に、setterのすべてのjava.lang.Stringプロパティをトリミングするために作成されたgetters/setters/equals/toString/etcのソーステンプレートを参照します。問題を解決するために、私は問題を抱えていた1つのクラスをパッシベーションし、各ビルドで生成されなくなり、TINプロパティのトリムを削除しました。

2

私は、Hibernateのことは知りません。しかし、私はOracleが空の文字列をNull値として扱うことを知っています。そして、それに対する回避策はありません。これに対処するための

4

一つの方法は、create a Hibernate UserTypeにあります。 hibernate.orgのリンクには、Stringエスケープのための既成のクラスがいくつかあります。私はこれが直接9つの空白を空の文字列に変換しないように休止状態にする方法を教えてもらえませんが、データベース側の記憶域の問題は解決します。唯一の値を「」エスケープ(ご希望の方法で、あなたの9つのスペースのケースを処理することができる)すべての文字列をエスケープ1、および1 -

は、そのページ上の2つの実装があります。前者があなたに適しているように聞こえます。レコードの

- 私はこの方法を自分で利用しています。あなたがやらなければならないことは、あなたのクラスパスにクラスを持っている、と(すなわちあなたの財産要素にタイプ=「my.fully.qualified.HibernateUserType」を追加)完全修飾クラス名にあなたのhbm.xmlに「タイプ」属性を設定しています。

Java側では、クラスは引き続きjava.lang.Stringと見たい値を扱いますが、ハイバネート側ではUserTypeクラスを使用します。

+0

ありがとうございます。これはかなり良いアプローチのようです。私が見ている最大の問題は、Hibernateの外部でそのデータにアクセスするすべてのものは、値がエスケープされていることも認識していなければならないということです。私は、Hibernateトリミング値のこの動作が正常/文書化されているかどうか疑問に思っています。 – jlpp

+0

True - ハイバネート以外のデータベースにアクセスするコードの他の部分がある場合、それが問題です。 –

+0

残念ながら、これが当てはまります。フラットファイルをバッチ処理して同じ列を読み書きするストアドプロシージャがあります。しかし、ありがとう。あなたのことは確かな答えでした。 – jlpp

関連する問題