Difference between @GeneratedValue and @GenericGenerator
When using an ORM it is often necessary to generate a primary key value.
The @GeneratedValue
annotation denotes that a value for a column, which must be annotated with @Id
is generated. The elements strategy
and generator
on the annotation describe how the generated value is obtained.
There are four possible values for the strategy
element on the @GeneratedValue
annotation: IDENTITY
, AUTO
, TABLE
and SEQUENCE
. See more.
So to answer Part 2 of your question, the code snippet is indicating that the value of userId
will be obtained through a sequence in the database.
The generator
element of the @GeneratedValue
annotation denotes the name of the primary key generator. In Part1 of your question, the code snippet indicates that a generator
named increment
will be used to obtain the primary key value. increment
is then defined in the next annotation @GenericGenerator
. @GenericGenerator
is a hibernate annotation used to denote a custom generator, which can be a class or shortcut to a generator supplied by Hibernate. increment
is a shortcut to a Hibernate generator that:
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.
In the Third Part of your question, the code uses a hilo
Hibernate generator that:
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.
To extend the @kevin-bowersox's answer.
Relationships between the Hibernate primary key generation strategies and specific generator respectively, as specified in org.hibernate.id.IdentifierGeneratorFactory
static {
GENERATORS.put("uuid", UUIDHexGenerator.class); // "deprecated" for new use
GENERATORS.put("hilo", TableHiLoGenerator.class); // removed in Hibernate 5
GENERATORS.put("assigned", Assigned.class);
GENERATORS.put("identity", IdentityGenerator.class);
GENERATORS.put("select", SelectGenerator.class);
GENERATORS.put("sequence", SequenceGenerator.class);
GENERATORS.put("seqhilo", SequenceHiLoGenerator.class);
GENERATORS.put("increment", IncrementGenerator.class);
GENERATORS.put("foreign", ForeignGenerator.class);
GENERATORS.put("guid", GUIDGenerator.class);
GENERATORS.put("uuid.hex", UUIDHexGenerator.class); // uuid.hex is deprecated
GENERATORS.put("sequence-identity", SequenceIdentityGenerator.class);
}
In Hibernate 4.3 I've found org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory
class with 3 more strategies:
register("uuid2", UUIDGenerator.class);
register("enhanced-sequence", SequenceStyleGenerator.class);
register("enhanced-table", TableGenerator.class);
The above fifteen strategies, plus native
, are sixteen generation strategies supported in Hibernate by default.
Example with native
:
@GeneratedValue(generator = "nativeGenerator")
@GenericGenerator(name = "nativeGenerator", strategy = "native")
@Entity
@Table(name="Honey")
public class Honey implements Serializable{
private static final long serialVersionUID = 42L;
@Id
//@SequenceGenerator(name="honeySequence",sequenceName="HONEY_SEQ")
@org.hibernate.annotations.GenericGenerator(name="honeySequence", strategy = "sequence",
parameters = {
@Parameter(name="sequence", value="HONEY_SEQ") }
)
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="honeySequence")
private int Id;
private String name;
private String taste;
- @GeneratedValue is used only to get the generated value. The two arguments strategy and generator are used to define how the value is obtained.
- @GenericGenerator is used to map a user defined sequence generator with your hibernate session.
- You can also use @SequenceGenerator which i have commented in my code. This is not a simple sequence generator but a generator which work on HILO algorithm. Due to which you will find a lot of gaps in your sequence, like your first value will start from 50 because the default allocation size is 50.
So its better to use @GenericGenerator for your own architecture. But if you are bound to use @SequenceGenerator you have to manually edit your sequence to have two more attributes allocationSize=1 and initialValue=1. And to work with these attributes you need to add apropert in your hibernate.cfg.xml file
<property name="hibernate.id.new_generator_mappings">true</property>