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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2155376/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 02:22:03  来源:igfitidea点击:

How to use existing Oracle sequence to generate id in hibernate?

oraclehibernatesequence

提问by Vladimir

I have legacy Oracle db with a sequence named PRODUCT_ID_SEQ.

我有一个名为PRODUCT_ID_SEQ.

Here is the mapping of Productclass 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 allocationSizeproperty = 50. So that means that Hibernate doesn't actually use the sequence which is already defined in the db.

但是看起来 ids 的生成间隔为 50,例如 1000、1050、1100 等。这对应于allocationSizeproperty = 50的默认值。所以这意味着 Hibernate 实际上并没有使用已经在 db 中定义的序列.

How do I make Hibernate use the sequence?

如何让 Hibernate 使用该序列?

回答by Mike Demenok

The answer to the original question:

原始问题的答案:

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

It is allocationSizethat sets the value to increment by.

它是allocationSize设置要递增的值。

回答by rsilva4

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-identityuses auto increment with sequences.

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

回答by Tristan

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

这是一个带注释的工作示例,这样,将使用现有的数据库序列(您也可以使用“序列”策略,但插入性能较低):

@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;
    }

回答by jvergara

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>

回答by user1256936

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

回答by Maninder

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

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

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

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

I have tested both ways, which works just fine.

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

回答by shakhawat

allocationSizeand incrementByare completely different things.

allocationSizeincrementBy是完全不同的东西。

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 allocationSizedefault 50.

例如 - 假设当前序列值为 5,在 db 中增加 1allocationSize默认为 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 = 1as already answered will do the purpose

如果你不想要这个只是allocationSize = 1已经回答的设置就可以达到目的

回答by Summer

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;

回答by Eyal Lupu


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

艾尔

回答by bedjaoui djounaydi

First : you should create in your database the sequence like:

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

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

and in your file Product.hbm.xml configuration make :

并在您的文件 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>