Oracle Hibernate シーケンス ジェネレーターの問題
-
16-09-2019 - |
質問
oracle 11g、Java(struts2)、Hibernateを使用してアプリケーションを開発しています。
mytemp という名前のテーブルがあり、列 mytemp_id の型は NUMBER(22,0) です。
私のmytemp.hbm.xmlファイルのIDは以下のとおりです
<id name="mytempId" type="big_decimal">
<column name="MYTEMP_ID" precision="22" scale="0" />
<generator class="sequence">
<param name="sequence">MYTEMP_TEMP_ID_SEQ</param>
</generator>
</id>
私のOracleデータベースでは、「MYTEMP_TEMP_ID_SEQ」という名前のシーケンスが作成され、Oracleで正常に動作しています。
休止状態を使用してレコードを挿入しようとすると、次のエラーが表示されます
org.hibernate.id.IdentifierGenerationException:この ID ジェネレーターは、long、integer、short、または string を生成します。
私のシーケンスは Number を返すので、hibernate はそれを BigDecimal とみなしますが、hibernate のシーケンス ジェネレータ クラスは、long、integer、short、string のみの値を考慮しているようです。
Hibernate では BigDecimal に問題はないはずです。しかし、彼らはシーケンスジェネレーターにBigDecimalを実装していないと思います
誰か問題の解決を手伝ってくれませんか?
ありがとう。
解決
正直に言うと、なぜ ID を long ではなく BigDecimal にすることにこだわるのか、私には想像できません。最大のlong値は次のとおりです。 9,223,372,036,854,775,807
これは明らかに最大 NUMBER(22) 値の約 1,000 分の 1 ですが、実際には次のようにする必要があります。 十分に. 。生成するとしたら 百万 識別子 一秒ごと, 、あなたはそれをしなければならないでしょう 30万年 あなたのシーケンスを使い果たすために。
ただし、識別子を BigDecimal として生成するには、独自のジェネレーターを作成する必要があります。これを行うには、Hibernate の組み込み SequenceGenerator を拡張し、その SequenceGenerator をオーバーライドします。 generate()
方法。電話をかける代わりに IdentifierGeneratorFactory.get()
これは、結果セットから BigDecimal としてシーケンス値を取得する、long / int / short / String のみをサポートします。
次に必要となるのは、 ジェネレーターを宣言する 完全なクラス名を指定します。
<generator class="com.mypackage.BigDecimalGenerator">
<param name="sequence">MYTEMP_TEMP_ID_SEQ</param>
</generator>
他のヒント
あなたは正しい方言を設定しましたか?これは、Hibernateがシーケンスの結果を理解させるのに十分でなければならない。
[EDIT]問題は、あなたのシーケンスのタイプがあなたの列の型と一致しないということです。あなたのシーケンスがBigDecimalのを返しながら(Hibernateのエラーメッセージごとなど)のシーケンスは、長整数、短いまたは文字列にキャストすることができます。
私はOracleはその型を知らなくても「長い」などのID列の型を指定することをお勧めします。内部的には、Hibernateはその後、正しく皆のためにすべてを投じることができる必要があります。
確かに。ロングIDは常にそれが生成できるユニークなレコードの数を考えると、十分でなければなりません。特別な値を持っている単なる特定の発電機以外のかもしれません。の整数の種類以上に制御することが、の整数の何らかの理由でタイプ値(特定のプロジェクトかもしれません)。
また、発電機はそうdialact定義も問題ありません、Oracleのシーケンスのような特定のデータベースです。