Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between @GeneratedValue and @GenericGenerator

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>(); 
like image 926
user1883212 Avatar asked Aug 13 '13 09:08

user1883212


People also ask

What is @GenericGenerator in Hibernate?

@GenericGenerator is a hibernate annotation used to denote a custom generator, which can be a class or shortcut to a generator supplied by Hibernate.

What is the use of @GeneratedValue in spring boot?

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.

How does @GeneratedValue work?

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.

What is the use of @GeneratedValue strategy GenerationType Auto?

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.


2 Answers

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.

like image 81
Kevin Bowersox Avatar answered Oct 18 '22 03:10

Kevin Bowersox


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") 
like image 28
naXa Avatar answered Oct 18 '22 03:10

naXa