如何使用现有的Oracle序列在hibernate中生成id?

时间:2010-01-28 14:59:28

标签: oracle hibernate sequence

我有一个带有名为PRODUCT_ID_SEQ的序列的旧版Oracle数据库。

以下是我需要生成正确id的Product类的映射:

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

   ...
}

但看起来像id生成的间隔为50,如1000,1050,1100等。这对应于allocationSize property = 50的默认值。这意味着Hibernate实际上并没有使用已经在db中定义的序列。

如何让Hibernate使用序列?

10 个答案:

答案 0 :(得分:25)

原始问题的答案:

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

allocationSize将值设置为递增。

答案 1 :(得分: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>

您可以轻松地将其映射到注释。生成器 sequence-identity 使用带序列的自动递增。

答案 2 :(得分:8)

这是一个带注释的工作示例,这样,将使用现有的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 :(得分:6)

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

答案 4 :(得分:5)

在Oracle中创建序列名称,例如contacts_seq。 在您的POJO课程中。为序列定义以下注释。

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

答案 5 :(得分:4)

如果你使用javax.persistence.SequenceGenerator,hibernate使用hilo并且可能会在序列中产生大的间隙。有一篇帖子解决了这个问题:https://forum.hibernate.org/viewtopic.php?t=973682

有两种方法可以解决此问题

  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”)})

  3. 我已经测试了两种方式,效果很好。

答案 6 :(得分:2)

allocationSize incrementBy 完全不同。

Hibernate当然是使用在DB中创建的序列,但是根据allocationSize,您可能会在生成的值中找到差距。

例如 - 假设当前序列值为5,在db 中递增1, allocationSize 默认为50。

现在你要通过hibernate保存3个元素的集合 Hibernate将分配生成的id 250,251,252

这是出于优化目的。 Hibernate不必返回db并获取下一个递增的值。

如果您不希望这样设置allocationSize = 1已经回答,那么

答案 7 :(得分:1)

我在PostgreSQL上使用以下内容并且工作正常。

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

答案 8 :(得分:0)


默认情况下,Hibernate使用序列HiLo生成器,除非您有特殊需求,否则它很好(性能明智)。您可以在我的博客here

中阅读更多相关内容

的Eyal

答案 9 :(得分:0)

首先:您应该在数据库中创建如下序列:

CREATE SEQUENCE  "PRODUCT_ID_SEQ"  MINVALUE 0 MAXVALUE 1000000000 INCREMENT BY 1 START WITH 1 CACHE 500 NOORDER  NOCYCLE ;

并在文件Product.hbm.xml中进行配置:

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