A generator class is used to generate an ID for an object, which is going to be inserted in the database as a primary key. The ID is a unique identifier for the objects of the persistent class. We can use any generator classes in our application as per our requirements.
IDENTITY This GenerationType indicates that the persistence provider must assign primary keys for the entity using a database identity column. IDENTITY column is typically used in SQL Server. This special type column is populated internally by the table itself without using a separate sequence.
These fields define the database table used for generating the primary key and correspond to the @TableGenerator annotation. These fields apply only when Strategy = Table. Unique name of the generator.
If we want to automatically generate the primary key value, we can add the @GeneratedValue annotation. This can use four generation types: AUTO, IDENTITY, SEQUENCE and TABLE. If we don't explicitly specify a value, the generation type defaults to AUTO.
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.
Basically, you have two major choices:
@GeneratedValue
annotation and Hibernate will assign the identifier for you.For the generated identifiers you have two options:
For numerical identifiers you have three options:
IDENTITY
SEQUENCE
TABLE
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With