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

时间:2022-11-25 12:08:01

I have legacy Oracle db with a sequence named PRODUCT_ID_SEQ.

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

Here is the mapping of Product class for which I need generate correct ids:

这是Product类的映射,我需要生成正确的id:

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

   ...
}

But looks like ids are generated with an interval of 50, like 1000, 1050, 1100 etc. This corresponds to the default value of allocationSize property = 50. So that means that Hibernate doesn't actually use the sequence which is already defined in the db.

但看起来像id生成的间隔为50,如1000,1050,1100等。这对应于allocationSize属性的默认值= 50.这意味着Hibernate实际上并没有使用已在D b。

How do I make Hibernate use the sequence?

如何使Hibernate使用序列?

9 个解决方案

#1


24  

The answer to the original question:

原问题的答案:

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

It is allocationSize that sets the value to increment by.

allocSize将值设置为递增。

#2


17  

I'm not used to use annotations, this is what I have in my *.hbm.xml:

我不习惯使用注释,这是我在* .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>

You can easily map this to annotations. The generator sequence-identity uses auto increment with sequences.

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

#3


8  

Here is a working example with annotations, this way, the existing DB sequence will be used (you can also use the "sequence" strategy, but with less performance on insertion) :

这是一个带注释的工作示例,这样,将使用现有的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;
    }

#4


5  

Create your sequence name in Oracle, for example, contacts_seq. In Your POJO Class . Define the following annotation for your sequence.

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

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

#5


5  

I had the same issue while upgrading from 3.5.5 to 5.0.6.Final.

从3.5.5升级到5.0.6.Final时,我遇到了同样的问题。

I solved it by re-configuring mapping in the HBM file from:

我通过重新配置HBM文件中的映射来解决它:

    <generator class="sequence">
        <param name="sequence">PRODUCT_ID_SEQ</param>
    </generator>

to:

至:

    <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


4  

If you use javax.persistence.SequenceGenerator, hibernate use hilo and will possibly create large gaps in the sequence. There is a post addressing this problem: https://forum.hibernate.org/viewtopic.php?t=973682

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

there are two ways to fix this problem

有两种方法可以解决这个问题

  1. In the SequenceGenerator annotation, add allocationSize = 1, initialValue= 1

    在SequenceGenerator注释中,添加allocationSize = 1,initialValue = 1

  2. instead of using javax.persistence.SequenceGenerator, use org.hibernate.annotations, like this:

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

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

    @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") } )

    @ org.hibernate.annotations.GenericGenerator(name =“Question_id_sequence”,strategy =“sequence”,parameters = {@Parameter(name =“sequence”,value =“S_QUESTION”)})

I have tested both ways, which works just fine.

我测试了两种方式,效果很好。

#7


2  

I use following on PostgreSQL and works just fine.

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

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

#8


2  

allocationSize and incrementBy are completely different things.

allocationSize和incrementBy是完全不同的东西。

Hibernate is of course using your sequence created in DB but depending on allocationSize you might find gap in generated value.

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

For example- Let assume current sequence value is 5, increment by 1 in db, and allocationSize default 50.

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

Now you want to save a collection of 3 element through hibernate, then Hibernate will assign generated id 250, 251, 252

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

This is for optimization purpose. Hibernate doesn't have to go back to db and fetch next incremented value.

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

If you don't want this just setting allocationSize = 1 as already answered will do the purpose

如果您不希望这只是设置allocationSize = 1已经回答了将达到目的

#9


0  


By default Hibernate uses sequence HiLo generator which ,unless you have special needs, it is good (performance wise). You can read more of that in my blog here

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

Eyal

的Eyal

#1


24  

The answer to the original question:

原问题的答案:

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

It is allocationSize that sets the value to increment by.

allocSize将值设置为递增。

#2


17  

I'm not used to use annotations, this is what I have in my *.hbm.xml:

我不习惯使用注释,这是我在* .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>

You can easily map this to annotations. The generator sequence-identity uses auto increment with sequences.

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

#3


8  

Here is a working example with annotations, this way, the existing DB sequence will be used (you can also use the "sequence" strategy, but with less performance on insertion) :

这是一个带注释的工作示例,这样,将使用现有的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;
    }

#4


5  

Create your sequence name in Oracle, for example, contacts_seq. In Your POJO Class . Define the following annotation for your sequence.

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

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

#5


5  

I had the same issue while upgrading from 3.5.5 to 5.0.6.Final.

从3.5.5升级到5.0.6.Final时,我遇到了同样的问题。

I solved it by re-configuring mapping in the HBM file from:

我通过重新配置HBM文件中的映射来解决它:

    <generator class="sequence">
        <param name="sequence">PRODUCT_ID_SEQ</param>
    </generator>

to:

至:

    <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


4  

If you use javax.persistence.SequenceGenerator, hibernate use hilo and will possibly create large gaps in the sequence. There is a post addressing this problem: https://forum.hibernate.org/viewtopic.php?t=973682

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

there are two ways to fix this problem

有两种方法可以解决这个问题

  1. In the SequenceGenerator annotation, add allocationSize = 1, initialValue= 1

    在SequenceGenerator注释中,添加allocationSize = 1,initialValue = 1

  2. instead of using javax.persistence.SequenceGenerator, use org.hibernate.annotations, like this:

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

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

    @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") } )

    @ org.hibernate.annotations.GenericGenerator(name =“Question_id_sequence”,strategy =“sequence”,parameters = {@Parameter(name =“sequence”,value =“S_QUESTION”)})

I have tested both ways, which works just fine.

我测试了两种方式,效果很好。

#7


2  

I use following on PostgreSQL and works just fine.

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

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

#8


2  

allocationSize and incrementBy are completely different things.

allocationSize和incrementBy是完全不同的东西。

Hibernate is of course using your sequence created in DB but depending on allocationSize you might find gap in generated value.

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

For example- Let assume current sequence value is 5, increment by 1 in db, and allocationSize default 50.

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

Now you want to save a collection of 3 element through hibernate, then Hibernate will assign generated id 250, 251, 252

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

This is for optimization purpose. Hibernate doesn't have to go back to db and fetch next incremented value.

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

If you don't want this just setting allocationSize = 1 as already answered will do the purpose

如果您不希望这只是设置allocationSize = 1已经回答了将达到目的

#9


0  


By default Hibernate uses sequence HiLo generator which ,unless you have special needs, it is good (performance wise). You can read more of that in my blog here

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

Eyal

的Eyal