简体   繁体   English

使用JPA和Hibernate时如何选择id生成策略

[英]How to choose the id generation strategy when using JPA and Hibernate

I was going through Id generation section of the Hibernate reference guide and "java persistence with Hibernate"我正在阅读 Hibernate 参考指南的 Id 生成部分和“java persistence with Hibernate”

There are quite a few options available with Hibernate and JPA combined.结合 Hibernate 和 JPA 有很多选项可用。

I was looking for a further documentation on how to choose the specific id generation strategy.我一直在寻找有关如何选择特定 ID 生成策略的进一步文档。

I am also looking for tipping points.我也在寻找临界点。

For example, hilo strategy is expected to reduce contention.例如,hilo 策略有望减少争用。 I am assuming there must be a trade off associated with this choice.我假设必须有与此选择相关的权衡。

I want to be educated about the trade offs.我想接受有关权衡取舍的教育。

Is there any literature available?有文献可查吗?

The API Doc are very clear on this. API Doc对此非常清楚。

All generators implement the interface org.hibernate.id.IdentifierGenerator.所有生成器都实现接口 org.hibernate.id.IdentifierGenerator。 This is a very simple interface.这是一个非常简单的界面。 Some applications can choose to provide their own specialized implementations, however, Hibernate provides a range of built-in implementations.一些应用程序可以选择提供自己的专用实现,但是 Hibernate 提供了一系列内置实现。 The shortcut names for the built-in generators are as follows:内置生成器的快捷方式名称如下:

increment增量

generates identifiers of type long, short or int that are unique only when no other process is inserting data into the same table.生成 long、short 或 int 类型的标识符,这些标识符只有在没有其他进程向同一个表中插入数据时才是唯一的。 Do not use in a cluster.不要在集群中使用。

identity身份

supports identity columns in DB2, MySQL, MS SQL Server, Sybase and HypersonicSQL.支持 DB2、MySQL、MS SQL Server、Sybase 和 HypersonicSQL 中的标识列。 The returned identifier is of type long, short or int.返回的标识符是 long、short 或 int 类型。

sequence顺序

uses a sequence in DB2, PostgreSQL, Oracle, SAP DB, McKoi or a generator in Interbase.使用 DB2、PostgreSQL、Oracle、SAP DB、McKoi 中的序列或 Interbase 中的生成器。 The returned identifier is of type long, short or int返回的标识符是 long、short 或 int 类型

hilo希洛

uses a hi/lo algorithm to efficiently generate identifiers of type long, short or int, given a table and column (by default hibernate_unique_key and next_hi respectively) as a source of hi values.使用 hi/lo 算法有效地生成 long、short 或 int 类型的标识符,给定一个表和列(默认分别为 hibernate_unique_key 和 next_hi)作为 hi 值的来源。 The hi/lo algorithm generates identifiers that are unique only for a particular database. hi/lo 算法生成仅对特定数据库唯一的标识符。

seqhilo seqhilo

uses a hi/lo algorithm to efficiently generate identifiers of type long, short or int, given a named database sequence.使用 hi/lo 算法有效地生成 long、short 或 int 类型的标识符,给定一个命名的数据库序列。

uuid uuid

uses a 128-bit UUID algorithm to generate identifiers of type string that are unique within a.network (the IP address is used).使用 128 位 UUID 算法生成在 a.network 中唯一的字符串类型的标识符(使用 IP 地址)。 The UUID is encoded as a string of 32 hexadecimal digits in length. UUID 被编码为长度为 32 位十六进制数字的字符串。

guid向导

uses a database-generated GUID string on MS SQL Server and MySQL.在 MS SQL 服务器和 MySQL 上使用数据库生成的 GUID 字符串。

native本国的

selects identity, sequence or hilo depending upon the capabilities of the underlying database.根据底层数据库的功能选择标识、序列或 hilo。

assigned分配

lets the application assign an identifier to the object before save() is called.让应用程序在调用 save() 之前为 object 分配一个标识符。 This is the default strategy if no element is specified.如果没有指定元素,这是默认策略。

select select

retrieves a primary key, assigned by a database trigger, by selecting the row by some unique key and retrieving the primary key value.通过按某个唯一键选择行并检索主键值来检索由数据库触发器分配的主键。

foreign外国的

uses the identifier of another associated object. It is usually used in conjunction with a primary key association.使用另一个关联的标识符 object。它通常与主键关联一起使用。

sequence-identity序列同一性

a specialized sequence generation strategy that utilizes a database sequence for the actual value generation, but combines this with JDBC3 getGeneratedKeys to return the generated identifier value as part of the insert statement execution.一种专门的序列生成策略,它利用数据库序列来生成实际值,但将其与 JDBC3 getGeneratedKeys 结合起来以返回生成的标识符值作为插入语句执行的一部分。 This strategy is only supported on Oracle 10g drivers targeted for JDK 1.4.此策略仅在针对 JDK 1.4 的 Oracle 10g 驱动程序上受支持。 Comments on these insert statements are disabled due to a bug in the Oracle drivers.由于 Oracle 驱动程序中的错误,对这些插入语句的注释被禁用。

If you are building a simple application with not much concurrent users, you can go for increment, identity, hilo etc.. These are simple to configure and did not need much coding inside the db.如果您正在构建一个并发用户不多的简单应用程序,您可以使用 go 进行增量、标识、hilo等。这些配置简单,不需要在数据库中编写太多代码。

You should choose sequence or guid depending on your database.您应该根据您的数据库选择sequenceguid These are safe and better because the id generation will happen inside the database.这些是安全且更好的,因为id生成将在数据库内部发生。

Update: Recently we had an an issue with idendity where primitive type (int) this was fixed by using warapper type (Integer) instead.更新:最近我们遇到了一个身份问题,原始类型 (int) 通过使用 warapper 类型 (Integer) 来解决。

Basically, you have two major choices:基本上,您有两个主要选择:

  • You can generate the identifier yourself, in which case you can use an assigned identifier.您可以自己生成标识符,在这种情况下,您可以使用分配的标识符。
  • You can use the @GeneratedValue annotation and Hibernate will assign the identifier for you.您可以使用@GeneratedValue注释,Hibernate 将为您分配标识符。

For the generated identifiers you have two options:对于生成的标识符,您有两个选择:

  • UUID identifiers. UUID 标识符。
  • Numerical identifiers.数字标识符。

For numerical identifiers you have three options:对于数字标识符,您有以下三种选择:

IDENTITY is only a good choice when you cannot use SEQUENCE (eg MySQL) because it disables JDBC batch updates.只有当您不能使用SEQUENCE (例如 MySQL)时, IDENTITY才是一个不错的选择,因为它会禁用 JDBC 批量更新。

SEQUENCE is the preferred option, especially when used with an identifier optimizer like pooled or pooled-lo . SEQUENCE是首选选项,尤其是在与pooledpooled-lo等标识符优化器一起使用时。

TABLE is to be avoided since it uses a separate transaction to fetch the identifier and row-level locks which scales poorly.应避免使用TABLE ,因为它使用单独的事务来获取标识符和扩展性很差的行级锁。


A while ago i wrote a detailed article about Hibernate key generators: http://blog.eyallupu.com/2011/01/hibernatejpa-identity-generators.html前段时间写了一篇关于Hibernate密钥生成器的详细文章: http://blog.eyallupu.com/2011/01/hibernatejpa-identity-generators.html

Choosing the correct generator is a complicated task but it is important to try and get it right as soon as possible - a late migration might be a nightmare.选择正确的生成器是一项复杂的任务,但重要的是尽快尝试并正确选择 - 延迟迁移可能是一场噩梦。

A little off topic but a good chance to raise a point usually overlooked which is sharing keys between applications (via API).有点题外话,但这是一个很好的机会来提出一个通常被忽视的观点,即在应用程序之间共享密钥(通过 API)。 Personally I always prefer surrogate keys and if I need to communicate my objects with other systems I don't expose my key (even though it is a surrogate one) – I use an additional 'external key'.就个人而言,我总是更喜欢代理键,如果我需要将我的对象与其他系统通信,我不会公开我的密钥(即使它是代理键)——我使用一个额外的“外部密钥”。 As a consultant I have seen more than once 'great' system integrations using object keys (the 'it is there let's just use it' approach) just to find a year or two later that one side has issues with the key range or something of the kind requiring a deep migration on the system exposing its internal keys.作为一名顾问,我不止一次看到使用 object 密钥的“伟大”系统集成(“它就在那里让我们使用它”的方法)只是在一两年后发现一方在密钥范围或其他方面存在问题需要在系统上进行深度迁移并暴露其内部密钥的那种。 Exposing your key means exposing a fundamental aspect of your code to external constrains shouldn't really be exposed to.公开您的密钥意味着将您的代码的基本方面公开给外部约束,而这些约束实际上不应该公开。

I find this lecture very valuable https://vimeo.com/190275665 , in point 3 it summarizes these generators and also gives some performance analysis and guideline one when you use each one.我发现这个讲座非常有价值https://vimeo.com/190275665 ,在第 3 点中它总结了这些生成器,并在您使用每个生成器时给出了一些性能分析和指南。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM