官术网_书友最值得收藏!

Generating Primary Keys

Up to now we have relied on the application to set an entity's primary key by supplying a primary key identifier as a parameter. However, we may want to relieve the application of this responsibility and use automatically generated keys. JPA provides the Table, Sequence, Auto, and Identity strategies for generating primary keys.

Table Strategy

With this strategy the persistence engine uses a relational database table from which the keys are generated. This strategy has the advantage of portability; we can use it with any relational database. Here is an example of how we would specify a table generation strategy for the id attribute of the Customer entity:

@TableGenerator(name="CUST_SEQ",
table="SEQUENCE_TABLE",
pkColumnName="SEQUENCE_NAME",
valueColumnName="SEQUENCE_COUNT")
@Id
@GeneratedValue(strategy=GenerationType.TABLE,
generator="CUST_SEQ")
public int getId() { return id; }

First we use the @TableGenerator annotation to specify the table used for key generation. This annotation can be placed on the primary key attribute, as we have done here, or on the entity class.

The name element in our example CUST_SEQ, identifies the generator. The table element is the name of the table that stores the generated values. In our case we have chosen SEQUENCE_TABLE as the table name. There is a default table element, but this is dependent on the persistence engine being used. In the case of GlassFish, this table name is SEQUENCE. The pkColumnName element is the name of the primary key column in the sequence table. We have chosen SEQUENCE_NAME as the column name. Again the default is persistence engine dependent. In the case of GlassFish this value is SEQ_NAME. The valueColumnName element is the name of the column that stores the last key value generated. The default is persistence engine dependent. In the case of GlassFish this value is SEQ_COUNT.

One element of @TableGenerator for which we assumed the default is pkColumnValue. This is the String value that is entered in the pkColumnName column. The default is persistence engine dependent. In the case of GlassFish, this value is set to the name element of @TableGenerator. In our example this is CUST_SEQ. So SEQUENCE_TABLE will initially have the following row present:

SQL> SELECT * FROM SEQUENCE_TABLE;
SEQUENCE_NAME SEQUENCE_COUNT
------------- --------------
CUST_SEQ 0

If we want to store several sequences in the same sequence table, for example a separate sequence for each entity, then we need to manually specify the pkColumnValue element. The following statement sets the pkColumnValue to CUSTOMER_SEQ:

@TableGenerator(name="CUST_SEQ",
table="SEQUENCE_TABLE",
pkColumnName="SEQUENCE_NAME",
valueColumnName="SEQUENCE_COUNT",
pkColumnValue="CUSTOMER_SEQ")

We should mention two other @TableGenerator elements: initialValue and allocationSize. initialValue is the initial value assigned to the primary key sequence. The default value is 0. The sequence is incremented by a value of 1. The allocationSize is the cache size into which the persistence engine reads from the sequence table. The default value is 50.

The @GeneratedValue annotation specifies the key generation strategy with the strategy element. In our case we have chosen the TABLE strategy. The default strategy is AUTO which we describe later in this chapter. The generator element provides the name of the primary key generator. In our case this is CUST_SEQ and must match the name element of the @TableGenerator annotation. The @GeneratedValue annotation is a field-based or property-based annotation, so must be present immediately before the primary key field or getter method.

Sequence Strategy

Some databases, such as Oracle, have a built-in mechanism called sequences for generating keys. To invoke such a sequence we need to use the @SequenceGenerator annotation. For example:

@SequenceGenerator(name="CUST_SEQ",
sequenceName="CUSTOMER_SEQUENCE")

As with the @TableGenerator annotation, the name element identifies the generator. The sequenceName element identifies the database sequence object. initialValue is the initial value assigned to the primary key sequence. The default differs from the @TableGenerator equivalent, and is equal to 1. The allocationSize is the cache size into which the persistence engine reads from the sequence. The default value is 50.

The @SequenceGenerator annotation can be placed on the primary key attribute or on the entity class.

As with Table generated sequences, we use the @GeneratedValue annotation to specify the generation strategy. For example,

@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE,
generator="CUST_SEQ")

This time we have specified the SEQUENCE strategy. The name of the primary key generator is CUST_SEQ, and this must match the name element of the @SequenceGenerator annotation. Remember the @GeneratedValue annotation is a field-based or property-based annotation, so it must be present immediately before the primary key field or getter method.

Identity Strategy

Some databases, such as Microsoft SQL Server, use an identity column for generating keys. To use this we specify the IDENTITY strategy in the @GeneratedValue annotation:

@GeneratedValue(strategy=GenerationType.IDENTITY)

Note that there is no generator element that we have for the Table and Sequence strategies.

Auto Strategy

The final strategy is the AUTO strategy. With this strategy the persistence engine selects the strategy. In the case of GlassFish the TABLE strategy is selected. We can specify an AUTO strategy either explicitly:

@GeneratedValue(strategy=GenerationType.AUTO)

or implicitly:

@GeneratedValue

as the default strategy is AUTO.

In the case of GlassFish the default sequence table has the name SEQUENCE, with columns SEQ_NAME and SEQ_COUNT :

主站蜘蛛池模板: 象州县| 格尔木市| 永靖县| 二连浩特市| 义马市| 都江堰市| 松原市| 嘉鱼县| 巨鹿县| 会昌县| 贞丰县| 阿尔山市| 宜城市| 阿合奇县| 漠河县| 从化市| 滦南县| 新乐市| 桃源县| 通道| 临夏县| 安化县| 朝阳县| 林西县| 曲阳县| 清涧县| 南乐县| 榆社县| 阳原县| 平乡县| 衡南县| 湖北省| 土默特右旗| 麻阳| 伊川县| 区。| 黑龙江省| 定日县| 长治县| 镇平县| 元阳县|