PRODUCT_ID_SEQ
という名前のシーケンスを持つレガシーOracle dbがあります。
以下は、正しいIDを生成する必要があるProduct
クラスのマッピングです。
public class Product {
@GeneratedValue(strategy = GenerationType.SEQUENCE,
generator = "retailerRaw_seq")
@SequenceGenerator(name = "retailerRaw_seq",
sequenceName = "PRODUCT_ID_SEQ")
private Long id;
...
}
しかし、idは、1000、1050、1100など、50の間隔で生成されるように見えます。これは、allocationSize
property = 50のデフォルト値に対応します。したがって、Hibernateは実際にシーケンスを使用しませんはデータベースですでに定義されています。
Hibernateにシーケンスを使用させるにはどうすればよいですか?
元の質問に対する答え:
@SequenceGenerator(name="EL_SEQ", sequenceName="EL_SEQ",allocationSize=1)
インクリメントする値を設定するのはallocationSize
です。
私は注釈の使用に慣れていません。これは* .hbm.xmlにあります:
<id name="id" type="Java.lang.Integer">
<column name="ID_PRODUCT" />
<generator class="sequence-identity" >
<param name="sequence">PRODUCT_ID_SEQ</param>
</generator>
</id>
これを注釈に簡単にマッピングできます。ジェネレーターsequence-identityは、シーケンスで自動インクリメントを使用します。
アノテーションを使用した実際の例を次に示します。この方法では、既存のDBシーケンスが使用されます(「シーケンス」戦略も使用できますが、挿入時のパフォーマンスは低下します)。
@Entity
@Table(name = "USER")
public class User {
// (...)
@GenericGenerator(name = "generator", strategy = "sequence-identity", parameters = @Parameter(name = "sequence", value = "USER_SEQ"))
@Id
@GeneratedValue(generator = "generator")
@Column(name = "ID", unique = true, nullable = false, precision = 22, scale = 0)
public Long getId() {
return this.id;
}
3.5.5から5.0.6.Finalにアップグレードするときに同じ問題が発生しました。
HBMファイルのマッピングを次の場所から再構成することで解決しました。
<generator class="sequence">
<param name="sequence">PRODUCT_ID_SEQ</param>
</generator>
に:
<generator class="org.hibernate.id.enhanced.SequenceStyleGenerator">
<param name="prefer_sequence_per_entity">true</param>
<param name="optimizer">none</param>
<param name="increment_size">1</param>
<param name="sequence_name">PRODUCT_ID_SEQ</param>
</generator>
Oracleで、contacts_seqなどのシーケンス名を作成します。あなたのPOJOクラスで。シーケンスに次の注釈を定義します。
@Id
@GeneratedValue(strategy=GenerationType.AUTO, generator="my_seq_gen")
@SequenceGenerator(name="my_seq_gen", sequenceName="contacts_seq")
Javax.persistence.SequenceGeneratorを使用する場合、Hibernateはhiloを使用し、シーケンスに大きなギャップを作成する可能性があります。この問題に対処する投稿があります: https://forum.hibernate.org/viewtopic.php?t=973682
この問題を修正するには2つの方法があります
SequenceGeneratorアノテーションで、allocationSize = 1、initialValue = 1を追加します
javax.persistence.SequenceGeneratorを使用する代わりに、次のようにorg.hibernate.annotationsを使用します。
@ javax.persistence.SequenceGenerator(name = "Question_id_sequence"、sequenceName = "S_QUESTION")
@ org.hibernate.annotations.GenericGenerator(name = "Question_id_sequence"、strategy = "sequence"、parameters = {@Parameter(name = "sequence"、value = "S_QUESTION")})
私は両方の方法をテストしましたが、うまくいきます。
allocationSizeとincrementByはまったく異なるものです。
HibernateはもちろんDBで作成されたシーケンスを使用しますが、allocationSizeによっては、生成された値にギャップが見つかる場合があります。
たとえば、現在のシーケンス値が5、dbで1ずつ増加、およびallocationSizeデフォルト50であると仮定します。
Hibernateを使用して3つの要素のコレクションを保存したい場合、Hibernateは生成されたID 250、251、252を割り当てます
これは最適化のためです。 Hibernateはdbに戻って次の増分値を取得する必要はありません。
これが必要ない場合は、allocationSize = 1
すでに答えたように目的を果たす
私はPostgreSQLで以下を使用し、問題なく動作します。
@Id
@GeneratedValue(generator = "my_gen")
@SequenceGenerator(name = "my_gen", sequenceName = "my_seq_in_db")
private int userId;
まず、データベースに次のようなシーケンスを作成する必要があります。
CREATE SEQUENCE "PRODUCT_ID_SEQ" MINVALUE 0 MAXVALUE 1000000000 INCREMENT BY 1 START WITH 1 CACHE 500 NOORDER NOCYCLE ;
そして、ファイルProduct.hbm.xml構成makeで:
<class name="ProductPersistant" table="Product">
<id name="id" type="Java.lang.Long" column="productID" >
<generator class="sequence">
<param name="sequence">PRODUCT_ID_SEQ</param>
</generator>
</id>
。私のブログでそれをもっと読むことができます here
エヤル