2010-01-28 261 views
21

我有一個名爲PRODUCT_ID_SEQ的序列的遺留Oracle數據庫。如何使用現有的Oracle序列在hibernate中生成id?

這裏是Product類的映射,我需要生成正確的ID:

public class Product { 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, 
         generator = "retailerRaw_seq") 
    @SequenceGenerator(name = "retailerRaw_seq", 
         sequenceName = "PRODUCT_ID_SEQ") 
    private Long id; 

    ... 
} 

但是看起來像與50的間隔生成的ID,如1000,1050,1100等,這對應於默認值allocationSize property = 50.所以這意味着Hibernate實際上並沒有使用已經在db中定義的序列。

如何讓Hibernate使用序列?

+0

重複的問題:見http://stackoverflow.com/questions/1729723/hibernate -does-not-generate-identifier-when-using-oracle-sequence/1729753#1729753 – 2010-01-28 16:03:20

+2

不,它不是重複的。見下面的答案 – Tristan 2011-08-14 08:41:47

回答

17

我不習慣使用註釋,這是我在我的*的.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> 

您可以輕鬆地這個映射到註解。生成器序列標識使用帶序列的自動增量。

+1

這是爲了做到這一點(與XML)的正確方法見下文用註解 – Tristan 2011-08-14 08:40:33

+2

+1一個例子,記得在加上'<屬性名=「hibernate.jdbc.use_get_generated_keys在」>真'你'hibernate.cfg.xml'文件。 – Withheld 2014-02-13 13:37:03

0


默認情況下,Hibernate使用序列HiLo生成器,除非你有特殊需求,否則它是好的(性能明智)。你可以在我的博客here

的Eyal閱讀更多的是

+0

任何想法改變算法,說使用JPA批註彙集而不是hilo? – 2013-10-21 15:57:23

7

這裏是註釋,這樣一來,現有的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; 
    } 
+0

我發現使用這種技術時,它的工作,但我的數據庫增加它的id值2而不是1.任何想法爲什麼? – user898465 2013-10-16 00:05:53

+0

檢查甲骨文的序列定義,你可能有類似「CREATE SEQUENCE my_sequence 1個INCREMENT開始時由2」 – Tristan 2013-10-17 06:59:46

23

答案原來的問題:

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

這是allocationSize,設置要增加的值。

+6

Upvoted因爲這是一個正確的JPA解決方案而不是具體的Hibernate。然而,一個allocationSize = 1表示,一些需要從數據庫中每一次插入獲得,而不是一下子緩存大量的ID,所以它帶有一個非常小的性能下降。 – 2013-07-30 23:58:46

3

如果使用javax.persistence.SequenceGenerator,hibernate使用hilo並且可能會在序列中創建大的間隙。有一個後解決這一問題:https://forum.hibernate.org/viewtopic.php?t=973682

有解決這個問題

  1. 在SequenceGenerator註釋兩種方式,加allocationSize = 1,初值= 1

  2. ,而不是使用的javax使用org.hibernate.annotations,如下所示:

    @ javax.persistence.SequenceGenerator(name =「Question_id_sequence」,sequenceName =「S_QUESTION」)

    @ org.hibernate.annotations.GenericGenerator(名稱= 「Question_id_sequence」,戰略= 「序列」,參數= {@Parameter(名稱= 「序列」,值= 「S_QUESTION」)})

我已經測試了這兩種方式,它工作得很好。

2

我在PostgreSQL上使用以下代碼,工作得很好。

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

在Oracle中創建序列名稱,例如contacts_seq。 在你的POJO課堂上。爲您的序列定義以下注釋。

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

allocationSizeincrementBy是完全不同的事情。

Hibernate當然使用您在DB中創建的序列,但根據allocationSize,您可能會發現生成的值存在空隙。

對於示例 - 讓我們假設當前序列值是5,在DB遞增1,和allocationSize默認50

現在你想通過休眠節省3元的集合,然後 休眠將分配生成的id 250,251,252

這是爲了優化目的。 Hibernate不必返回數據庫並獲取下一個遞增的值。

如果你不希望這只是設置allocationSize = 1因爲已經回答會做的目的

3

我有同樣的問題,同時從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> 
+0

是否需要將increment_size設置爲1?這不是默認值嗎? – 2017-10-26 09:12:07

相關問題