web-dev-qa-db-ja.com

既存のOracleシーケンスを使用してHibernateでIDを生成する方法は?

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にシーケンスを使用させるにはどうすればよいですか?

25
Vladimir

元の質問に対する答え:

@SequenceGenerator(name="EL_SEQ", sequenceName="EL_SEQ",allocationSize=1)

インクリメントする値を設定するのはallocationSizeです。

27
Mike Demenok

私は注釈の使用に慣れていません。これは* .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は、シーケンスで自動インクリメントを使用します。

18
rsilva4

アノテーションを使用した実際の例を次に示します。この方法では、既存の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;
    }
9
Tristan

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>
6
jvergara

Oracleで、contacts_seqなどのシーケンス名を作成します。あなたのPOJOクラスで。シーケンスに次の注釈を定義します。

@Id
@GeneratedValue(strategy=GenerationType.AUTO, generator="my_seq_gen")
@SequenceGenerator(name="my_seq_gen", sequenceName="contacts_seq")
5
user1256936

Javax.persistence.SequenceGeneratorを使用する場合、Hibernateはhiloを使用し、シーケンスに大きなギャップを作成する可能性があります。この問題に対処する投稿があります: https://forum.hibernate.org/viewtopic.php?t=973682

この問題を修正するには2つの方法があります

  1. SequenceGeneratorアノテーションで、allocationSize = 1、initialValue = 1を追加します

  2. 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")})

私は両方の方法をテストしましたが、うまくいきます。

4
Maninder

allocationSizeincrementByはまったく異なるものです。

HibernateはもちろんDBで作成されたシーケンスを使用しますが、allocationSizeによっては、生成された値にギャップが見つかる場合があります。

たとえば、現在のシーケンス値が5、dbで1ずつ増加、およびallocationSizeデフォルト50であると仮定します。

Hibernateを使用して3つの要素のコレクションを保存したい場合、Hibernateは生成されたID 250、251、252を割り当てます

これは最適化のためです。 Hibernateはdbに戻って次の増分値を取得する必要はありません。

これが必要ない場合は、allocationSize = 1すでに答えたように目的を果たす

2
shakhawat

私はPostgreSQLで以下を使用し、問題なく動作します。

 @Id
 @GeneratedValue(generator = "my_gen")
 @SequenceGenerator(name = "my_gen", sequenceName = "my_seq_in_db")
 private int userId;
1
Summer

まず、データベースに次のようなシーケンスを作成する必要があります。

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>
0


。私のブログでそれをもっと読むことができます here

エヤル

0
Eyal Lupu