Sometimes I find them together, sometimes alone... other times they seem to do the same.
What's the difference?
Here are three examples. What do they do of different? Why can't I use just @GeneratedValue for all of them?
Example 1
@Id @GeneratedValue(generator="increment") @GenericGenerator(name="increment", strategy = "increment") Long id;
Example 2
@Id @GeneratedValue(strategy=GenerationType.SEQUENCE) private int userId;
Example 3
@ElementCollection @JoinTable(name="Address", joinColumns=@JoinColumn(name="user_id") ) @GenericGenerator(name="hilo-gen", strategy="hilo") @CollectionId(columns = @Column(name="Address_id"), generator = "hilo-gen", type = @Type(type="long")) Collection<Addr> listOfAddresses = new ArrayList<Addr>();
@GenericGenerator is a hibernate annotation used to denote a custom generator, which can be a class or shortcut to a generator supplied by Hibernate.
You can change that by referencing the name of a @SequenceGenerator in the generator attribute of the @GeneratedValue annotation. The @SequenceGenerator annotation lets you define the name of the generator, the name, and schema of the database sequence and the allocation size of the sequence.
The @GeneratedValue annotation tells the ORM how to figure out the value of that field. Typcial generators you will run into. It is possible to develop custom generator. The interaction with the database will depend on generation strategy.
AUTO This GenerationType indicates that the persistence provider should automatically pick an appropriate strategy for the particular database. This is the default GenerationType, i.e. if we just use @GeneratedValue annotation then this value of GenerationType will be used.
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")
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