105

I was going through Id generation section of the Hibernate reference guide and "java persistence with Hibernate"

There are quite a few options available with Hibernate and JPA combined.

I was looking for a further documentation on how to choose the specific id generation strategy.

I am also looking for tipping points.

For example, hilo strategy is expected to reduce contention. 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?

Vlad Mihalcea
  • 103,297
  • 39
  • 432
  • 788

4 Answers4

94

The API Doc are very clear on this.

All generators implement the interface 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. 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. 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 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. The hi/lo algorithm generates identifiers that are unique only for a particular database.

seqhilo

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

uuid

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

guid

uses a database-generated GUID string on MS SQL Server and MySQL.

native

selects identity, sequence or hilo depending upon the capabilities of the underlying database.

assigned

lets the application assign an identifier to the object before save() is called. This is the default strategy if no element is specified.

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.

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. This strategy is only supported on Oracle 10g drivers targeted for JDK 1.4. Comments on these insert statements are disabled due to a bug in the Oracle drivers.

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.

You should choose sequence or guid depending on your database. These are safe and better because the id generation will happen inside the database.

Update: Recently we had an an issue with idendity where primitive type (int) this was fixed by using warapper type (Integer) instead.

Community
  • 1
  • 1
ManuPK
  • 10,995
  • 9
  • 54
  • 75
  • Thank you very much for your response. I have looked at the docs already. However, I am looking for why people would use something like hilo and seqhilo. When do we make that choice. What are the use cases for select. –  Apr 06 '12 at 15:33
  • When there is something as straightforward as sequence or guid, what can require a the developer to choose other avenues. –  Apr 06 '12 at 15:43
  • 1
    I have updated my answer. Actually **increment, identity, hilo** etc.. are simpler. but they are not suited for enterprise applications. Keeping all options is not a problem, but make sure you use the best suited one for you! – ManuPK Apr 08 '12 at 06:16
  • Yeah. So far I did not have the privilege to upvote or accept. –  Apr 29 '12 at 14:46
  • I am looking at diving into more details, if you have time do let me know. –  Apr 29 '12 at 14:46
  • I recently used hilo strategy for a table which had high concurrent inserts and reads, but no updates. I am planning to do some experiments to find statistics. I will publish it. –  Apr 29 '12 at 14:47
  • Hilo has the advantage of being cross-database in a simple straight-forward way since it's based on a simple table. I use it in an app that has to support MySQL, Oracle and MSSQL. – Pierre Henry Aug 16 '13 at 13:01
  • You said *sequence* and *guid* id generation happens inside database. Are you implying that *increment* *identity* etc do not happen inside database? – Kumar Manish Jun 11 '17 at 08:01
50

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.

For the generated identifiers you have two options:

  • UUID identifiers.
  • Numerical identifiers.

For numerical identifiers you have three options:

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

SEQUENCE is the preferred option, especially when used with an identifier optimizer like pooled or pooled-lo.

TABLE is to be avoided since it uses a separate transaction to fetch the identifier and row-level locks which scales poorly.

Vlad Mihalcea
  • 103,297
  • 39
  • 432
  • 788
20


A while ago i wrote a detailed article about Hibernate key generators: 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). 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. Exposing your key means exposing a fundamental aspect of your code to external constrains shouldn’t really be exposed to.

Eyal Lupu
  • 802
  • 9
  • 9
2

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.

Adelin
  • 15,139
  • 20
  • 96
  • 143