How to choose an identity generation strategy when using JPA and Hibernate

I went through the Id generation section of the Hibernate reference manual and "java persistence with Hibernate"

Hibernate and JPA have several options.

I was looking for additional documentation on how to choose a specific identifier generation strategy.

I am also looking for tipping points.

For example, the hilo strategy is expected to reduce competition. I suggest that there should be a compromise associated with this choice.

I want to get an education about compromises.

Is there any literature?

+83
java uniqueidentifier hibernate jpa
Apr 6 2018-12-12T00:
source share
4 answers

The Doc APIs are very clear.

All generators implement the org.hibernate.id.IdentifierGenerator interface. This is a very simple interface. Some applications may choose their own custom implementations, but Hibernate provides a number of built-in implementations. The shortcut names for the built-in generators are as follows:

increment

generates identifiers of type long, short or int, which are unique only when another process does not insert data into the same table. Do not use in a cluster.

identity

supports identity columns in DB2, MySQL, MS SQL Server, Sybase, and HypersonicSQL. The returned identifier is of type long, short, or int.

sequence

uses a sequence in DB2, PostgreSQL, Oracle, SAP DB, McKoi, or a generator in Interbase. The returned identifier is of type long, short, or int

Hilo

uses the hi / lo algorithm to efficiently generate identifiers of type long, short or int, given the table and column (by default, hibernate_unique_key and next_hi, respectively) as a source of hi values. The hi / lo algorithm generates identifiers that are unique to a specific database only.

seqhilo

uses the hi / lo algorithm to efficiently generate identifiers of type long, short or int with a given named database sequence.

Uuid

uses a 128-bit UUID algorithm to generate type string identifiers that are unique on the network (using an IP address). The UUID is encoded as a string of 32 hexadecimal digits in length.

reference

uses the GUID string generated by the database on MS SQL Server and MySQL.

native

selects an identifier, sequence, or hilo depending on the capabilities of the underlying database.

assigned

Allows an application to assign an identifier to an object before calling save (). This is the default strategy if no items are specified.

select

retrieves the primary key assigned by the database trigger by selecting a row using some unique key and obtaining the primary key value.

foreign

uses the identifier of another related object. It is commonly used in conjunction with a primary key association.

sequence identity

A specialized sequence generation strategy that uses the database sequence to generate the actual value, but combines it with JDBC3 getGeneratedKeys to return the generated identifier value as part of the insert statement. This strategy is only supported for Oracle 10g drivers targeting JDK 1.4. Comments on these insert statements are disabled due to an error in the Oracle drivers.

If you are creating a simple application with a small number of concurrent users, you can switch to increment, identifier, hilo , etc. They are easy to configure and do not need much encoding inside db.

Depending on your database, you must choose a sequence or guid . This is safe and better, because id generation will occur inside the database.

Update: Recently we had a problem with idendity, where the primitive type (int) was fixed using the warapper (Integer) type.

+78
Apr 6 2018-12-12T00:
source share

Basically, you have two main options:

  • You can generate the identifier yourself, in which case you can use the assigned identifier .
  • You can use the @GeneratedValue annotation, and Hibernate will assign you an identifier.

For generated identifiers, you have two options:

  • UUIDs
  • Numeric identifiers.

For numeric identifiers , you have three options :

  • IDENTITY
  • SEQUENCE
  • Table

IDENTIFICATION is only a good choice if you cannot use SEQUENCE (e.g. MySQL) because it disables JDBC batch updates .

SEQUENCE is the preferred option, especially when using an identifier optimizer, such as concatenated or concatenated-lo .

TABLE should be avoided at all costs , as it uses a separate transaction to retrieve row-level identifiers and locks that do not scale well.

+32
Jul 15 '16 at 8:11
source share


Some time ago, I wrote a detailed article about Hibernate key generators: http://blog.eyallupu.com/2011/01/hibernatejpa-identity-generators.html

Choosing the right generator is a difficult task, but it's important to try to fix it as soon as possible - late migration can be a nightmare.

A little off topic, but a good chance to raise the point that is usually ignored, which shares the keys between applications (via the API). Personally, I always prefer surrogate keys, and if I need to transfer my objects with other systems, I do not disclose my key (even if it is surrogate) - I use an additional "foreign key". As a consultant, I saw more than once "excellent" system integrations using object keys (the approach "he allows you to use it") to find a year or two later, when one side has problems with the key range or something like type, requiring deep migration in the system, exposing its internal keys. Providing your key facility by subjecting the fundamental aspect of your code to external constraints should not be affected.

+19
Nov 03
source share

I find this lecture very valuable https://vimeo.com/190275665 , in paragraph 3 it summarizes these generators, and also gives some performance analysis and recommendations when you use each of them.

+2
Feb 06 '17 at 21:14
source share



All Articles