在使用 @GeneratedValue 注解时,主键 id 是如何生成的?

huangapple go评论79阅读模式
英文:

Oracle : How primary key id is generated in case of @GeneratedValue annotation

问题

所以我有一个存储库类,在这个类里我可以看到主键字段有一个注解

@Id
@GeneratedValue

所以,我知道当没有明确定义策略时,默认设置的策略是自动(auto)。而在自动策略的情况下,底层数据库会从序列(Sequence)、表(Table)、自增(Identity)中选择策略。

所以,我的数据库是Oracle,在Oracle的情况下,序列(Sequence)是最常用的策略。

如果我理解有误,请纠正我。

我的问题是如何知道我的表使用了哪种策略,是序列(Sequence),并且如果是序列,它是针对特定表还是通用的?

而且,这个序列是否确保新的ID大于最大ID?

我在这个领域相当新手,找不到任何有用的资源来理解这个问题。

非常感谢您提前的帮助。 在使用 @GeneratedValue 注解时,主键 id 是如何生成的?

英文:

So I have a repository class in which I can see the primary key field has a annotation

@Id
@GeneratedValue

So, what I know that when the strategy is not explicitly defined the default strategy set is auto.
And in the case of auto strategy the undermine database decides the strategy from: Sequence, Table, Identity.

So, my database is Oracle, in case of Oracle, sequence is the most preferred strategy.

Correct me if I am wrong.

My question is how I can know which strategy is used by my table, is it sequence and if sequence, is it table specific or universal.

And is this sequence ensuring that the new id is greater than max id.

I am quite new in this field, and not able to find any useful resource for understanding this.

Thanks for your help in advance. 在使用 @GeneratedValue 注解时,主键 id 是如何生成的?

答案1

得分: 1

我非常确定,如果你配置了 ddl auto,那么这肯定是针对特定表的序列。在谷歌中搜索 JPA,你可以找到大量关于此主题的文章,比如:

https://www.objectdb.com/java/jpa/entity/generated

序列策略

序列策略由两部分组成 - 定义一个命名序列并在一个或多个类的一个或多个字段中使用该命名序列。@SequenceGenerator 注解用于定义序列,接受一个名称、一个初始值(默认为 1)和一个分配大小(默认为 50)。序列对应用程序是全局的,可以被一个或多个类中的一个或多个字段使用。SEQUENCE 策略在 @GeneratedValue 注解中用于将给定字段关联到先前定义的命名序列:

@Entity
// 定义一个序列 - 也可以位于另一个类中:
@SequenceGenerator(name="seq", initialValue=1, allocationSize=100)
public class EntityWithSequenceId {
    // 使用上面定义的序列:
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="seq")
    @Id long id;
}

AUTOIDENTITY 不同,SEQUENCE 策略会在新实体对象持久化时(即在提交之前)立即生成自动值。这在需要更早获得主键值时可能很有用。为了将往返到数据库服务器的次数减至最少,ID 被分组分配。每个分配中的 ID 数量由 allocationSize 属性指定。可能会有一些未使用的分配中的 ID。因此,此策略不能保证序列值不会有间隔。

表策略

TABLE 策略与 SEQUENCE 策略非常相似:

@Entity
@TableGenerator(name="tab", initialValue=0, allocationSize=50)
public class EntityWithTableId {
    @GeneratedValue(strategy=GenerationType.TABLE, generator="tab")
    @Id long id;
}

基于 ORM 的 JPA 提供程序(如 Hibernate、TopLink、EclipseLink、OpenJPA、JPOX 等)使用表来模拟序列以支持此策略。ObjectDB 没有表,因此 TABLE 和 SEQUENCE 策略几乎相同。

微小的区别与初始值属性有关。虽然 SEQUENCE 策略维护要使用的下一个序列号,但 TABLE 策略维护上次使用的最后一个值。对于 initialValue 属性的影响是,如果你希望序列号在 TABLE 策略中以 1 开头,则必须在 @SequenceGenerator 注解中指定 initialValue=0

或者:
https://vladmihalcea.com/why-you-should-never-use-the-table-identifier-generator-with-jpa-and-hibernate/

甚至这篇文章解释了序列策略在基准代码段中具有更好的性能:https://vladmihalcea.com/why-you-should-never-use-the-table-identifier-generator-with-jpa-and-hibernate/

如果你的技术栈是 spring-data-jpa,他们在 pivotal 上有非常好的文档。
https://spring.io/projects/spring-data-jpa

英文:

I'm quite sure it is table specific sequences if you configured ddl auto.
Search for JPA in Google to find a bunch of articles about the subject like :

https://www.objectdb.com/java/jpa/entity/generated

The Sequence Strategy

The sequence strategy consists of two parts - defining a named sequence and using the named sequence in one or more fields in one or more classes. The @SequenceGenerator annotation is used to define a sequence and accepts a name, an initial value (the default is 1) and an allocation size (the default is 50). A sequence is global to the application and can be used by one or more fields in one or more classes. The SEQUENCE strategy is used in the @GeneratedValue annotation to attach the given field to the previously defined named sequence:

@Entity
// Define a sequence - might also be in another class:
@SequenceGenerator(name="seq", initialValue=1, allocationSize=100)
public class EntityWithSequenceId {
    // Use the sequence that is defined above:
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="seq")
    @Id long id;
}

Unlike AUTO and IDENTITY, the SEQUENCE strategy generates an automatic value as soon as a new entity object is persisted (i.e. before commit). This may be useful when the primary key value is needed earlier. To minimize round trips to the database server, IDs are allocated in groups. The number of IDs in each allocation is specified by the allocationSize attribute. It is possible that some of the IDs in a given allocation will not be used. Therefore, this strategy does not guarantee there will be no gaps in sequence values.

The Table Strategy

The TABLE strategy is very similar to the SEQUENCE strategy:

@Entity
@TableGenerator(name="tab", initialValue=0, allocationSize=50)
public class EntityWithTableId {
    @GeneratedValue(strategy=GenerationType.TABLE, generator="tab")
    @Id long id;
}

ORM-based JPA providers (such as Hibernate, TopLink, EclipseLink, OpenJPA, JPOX, etc.) simulate a sequence using a table to support this strategy. ObjectDB does not have tables, so the TABLE and SEQUENCE strategies are almost identical.

A tiny difference is related to the initial value attribute. Whereas the SEQUENCE strategy maintains the next sequence number to be used the TABLE strategy maintains the last value that was used. The implication for the initialValue attribute is that if you want sequence numbers to start with 1 in the TABLE strategy initialValue=0 has to be specified in the @SequenceGenerator annotation.

or :
https://vladmihalcea.com/why-you-should-never-use-the-table-identifier-generator-with-jpa-and-hibernate/

Even this article that explains that sequence strategy have far best performances with benchmarked code snippets : https://vladmihalcea.com/why-you-should-never-use-the-table-identifier-generator-with-jpa-and-hibernate/

If your stack is spring-data-jpa they have a very good documentation on pivotal.
https://spring.io/projects/spring-data-jpa

huangapple
  • 本文由 发表于 2020年9月29日 15:13:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/64114599.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定