How to specify an ID policy
In JPA, we specify ID primary key and ID policy through @id and @generatedvalue, such as:
@Id
@GeneratedValue (strategy = Generationtype.auto)
@Column (name = "Id")
private String ID;
This also specifies the ID and the policy used to generate the ID, so let's take a look at what the strategies are. 4 JPA Policy Usage
We point into the @generatedvalue source can be seen, strategy property is specified by GenerationType, we point into the generationtype inside can see here define four kinds of strategy:
- Table: Use a specific database table to save the primary key.
- SEQUENCE: Generates a primary key based on the sequence of the underlying database, provided the database supports the sequence.
- IDENTITY: Primary key is automatically generated by the database (mainly auto-growth type)
- Auto: The primary key is controlled by the program (also default, when you specify a primary key, if you do not specify a primary key generation policy, auto is the default)
These policies are not supported by all databases and are supported by the following table:
policies \ Database |
MySQL |
Oracle |
PostgreSQL |
Kingbase |
TABLE |
Support |
Support |
Support |
Support |
SEQUENCE |
Not supported |
Support |
Support |
Support |
IDENTITY |
Support |
Not supported |
Support |
Support |
AUTO |
Support |
Support |
Support |
Support |
Hibernate extended ID policy
Of course, there are a few strategies that are not enough, and hibernate also expands on the JPA ID policy, which we can see in Org.hibernate.id.IdentifierGeneratorFactory, which mainly provides these strategies:
1.native: for Oracle in sequence mode, for MySQL and SQL Server with identity (self-increment primary key generation mechanism), native is the primary key generation work to the database to complete, hibernate regardless (very common).
2.UUID: A 128-bit UUID algorithm is used to generate the primary key, and the UUID is encoded as a 32-bit 16-digit string. Occupies large space (string type).
3.Hilo: Using the Hilo build policy, to create an additional table in the database, the default table name is Hibernate_unique_key, the default field is the integer type and the name is Next_hi (less used).
4.assigned: The primary key is handled by the program when inserting data (very often), which is the default build policy when the generator element is not specified. is equivalent to auto in JPA.
5.Identity: Using the SQL Server and MySQL self-increment fields, this method can not be placed in Oracle, Oracle does not support the self-increment field, to set sequence (MySQL and SQL Server is very common). Equivalent to the identity in JPA.
6.Select: Use triggers to generate primary keys (primarily for early database primary key generation mechanisms, and less).
7.sequence: Call the sequence of the underlying database to generate the primary key, or hibernate cannot find it if you want to set the sequence name.
8.Seqhilo: Implemented through the Hilo algorithm, but the primary key history is saved in sequence and is applicable to databases that support sequence, such as Oracle (less useful).
9.Increment: Hibernate will add a self-incremented primary key to the primary key when inserting the data, but a hibernate instance maintains a counter, so this method cannot be used when multiple instances are running.
10.Foreign: Use the primary key of another associated object. Commonly used and combined.
11.GUID: Using the database's underlying GUID algorithm mechanism, corresponding to the MySQL uuid () function, SQL Server's NEWID () function, Oracle's Rawtohex (SYS_GUID ()) function, etc.
12.Uuid.hex: See UUID, suggest to replace with UUID.
13.sequence-identity: Sequence policy extension, the use of an immediate retrieval strategy to obtain sequence value, need JDBC3.0 and JDK4 above (including 1.4) version.
The specific use is to have a @genericgenerator annotation, specify a policy, specify a custom name, and then use the policy in @generatedvalue, such as:
@Id
@GeneratedValue (Generator = "Myidstrategy")
@GenericGenerator (name = "Myidstrategy", strategy = " UUID ")
@Column (name =" id ")
private String ID;
Other similar, there are no more examples.
There are already a lot of strategies for us to use, but sometimes, such as a distributed system requires a global ID unique, or some other scenario that requires us to have our own strategy, then what to do. the ID policy used (take snowflake as an example)
When looking at other strategy source code, we found that they implemented such an interface Identifiergenerator, he is located in the Org.hibernate.id package, we enter the class, we can see the source code note that the user implementation of this interface can implement a custom ID policy
So it's easy, let's implement this interface:
public class Snowflakeid implements identifiergenerator{
...
@Override public
Serializable Generate (sessionimplementor s, Object obj) {
return getId () + "";
}
}
To implement the Generate method, the method body calls us to generate the ID method is good, here omitted the generation process, there is need to go to my code to find.
Note : The Identifiergenerator interface also writes a comment that must implement a default parameterless construct. At that time the realization of the less read this sentence, tossing a long (manual cover face). So this is roughly the case:
public class Snowflakeid implements identifiergenerator{public
Snowflakeid () {
}
...
@Override public
Serializable Generate (sessionimplementor s, Object obj) {
return getId () + "";
}
}
After customizing, we only need to use our custom when we specify the policy, @GenericGenerator the strategy attribute of the annotations, the use of a non-default policy requires the use of a full class name, namely:
@Id
@GeneratedValue (generator = "Snowflakeid")
@GenericGenerator (name = "Snowflakeid", strategy = " Top.felixu.idworker.SnowflakeId ")
@Column (name =" id ")
private String ID;
So that we can implement our own ID policy, example code
Broken code