Difference between revisions of "EclipseLink/UserGuide/JPA/Basic JPA Development/Entities/Ids/GeneratedValue"

From Eclipsepedia

Jump to: navigation, search
 
(40 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 
{{EclipseLink_UserGuide
 
{{EclipseLink_UserGuide
 
|info=y
 
|info=y
|toc=n
+
|toc=y
 
|eclipselink=y
 
|eclipselink=y
|eclipselinktype=JPA}}
+
|eclipselinktype=JPA
=@GeneratedValue Annotation=
+
|api=y
Use the <tt>@GeneratedValue</tt> annotation to enable EclipseLink persistence provider to generate unique identifiers for entity primary keys (see [[EclipseLink/UserGuide/JPA/Basic JPA Development/Mapping/Entity/Id|@Id]]).
+
|apis=
 +
*[http://www.eclipse.org/eclipselink/api/latest/javax/persistence/GeneratedValue.html @GeneratedValue]
 +
*[http://www.eclipse.org/eclipselink/api/latest/javax/persistence/SequenceGenerator.html @SequenceGenerator]
 +
*[http://www.eclipse.org/eclipselink/api/latest/javax/persistence/TableGenerator.html @TableGenerator]
 +
|nativeapi=y
 +
|nativeapis=
 +
*[http://www.eclipse.org/eclipselink/api/latest/org/eclipse/persistence/sequencing/Sequence.html Sequence]
 +
*[http://www.eclipse.org/eclipselink/api/latest/org/eclipse/persistence/sequencing/TableSequence.html TableSequence]
 +
*[http://www.eclipse.org/eclipselink/api/latest/org/eclipse/persistence/sequencing/NativeSequence.html NativeSequence]
 +
*[http://www.eclipse.org/eclipselink/api/latest/org/eclipse/persistence/sequencing/QuerySequence.html QuerySequence]
 +
*[http://www.eclipse.org/eclipselink/api/latest/org/eclipse/persistence/sequencing/UnaryTableSequence.html UnaryTableSequence]
 +
|examples=y
 +
|example=
 +
*[[EclipseLink/Examples/JPA/PrimaryKey|How to Configure Primary Key Generation]]
 +
*[[EclipseLink/Examples/JPA/CustomSequencing|How to use Custom Sequencing (UUID)]]}}
 +
=@GeneratedValue=
 +
 
 +
Use the <tt>@GeneratedValue</tt> annotation or <code><generated-value></code> XML element to enable the EclipseLink persistence provider to generate unique identifiers for entity primary keys (see [[EclipseLink/UserGuide/JPA/Basic JPA Development/Entities/Ids/Id|@Id]]).
 
{{EclipseLink_Spec
 
{{EclipseLink_Spec
|section=Section 9.1.9 "GeneratedValue Annotation"
+
|section=Section 11.1.17 "GeneratedValue Annotation"
 
}}
 
}}
  
 
+
Use the <tt>@GeneratedValue</tt> annotation to:
This annotation lets you do the following:
+
* Override the type of identity value generation selected by the persistence provider for your database if you feel another generator type is more appropriate for your database or application.
* override the type of identity value generation selected by the persistence provider for your database if you feel another generator type is more appropriate for your database or application;
+
* Override the generator name to reference your own customized <code>SequenceGenerator</code> or <code>TableGenerator</code>.
* override the primary key generator name selected by the persistence provider if this name is awkward, a reserved word, incompatible with a preexisting data model, or invalid as a primary key generator name in your database.
+
  
 
The <tt>@GeneratedValue</tt> annotation has the following attributes:
 
The <tt>@GeneratedValue</tt> annotation has the following attributes:
Line 21: Line 37:
 
<tr>
 
<tr>
 
<td>'''<tt>generator</tt>'''</td>
 
<td>'''<tt>generator</tt>'''</td>
<td>The default value of this attribute is the name that EclipseLink persistence provider assigns to the primary key generator it selects.<br>If the generator name is awkward, a reserved word, incompatible with a preexisting data model, or invalid as a primary key generator name in your database, set the value of this attribute to the <tt>String</tt> generator name you want to use.</td>
+
<td>The name of the <code>SequenceGenerator</code> or <code>TableGenerator</code> object use for this generated value.
<td>The name that EclipseLink persistence provider assigns to the primary key generator it selects</td>
+
If no generator is defined for this name, a generator is defaulted.  For a <tt>SEQUENCE</tt> generator the name becomes the name of the database sequence object.
 +
For a <tt>TABLE</tt> generator the name becomes the value for the sequence row in the sequence table.</td>
 +
<td><tt>SEQ_GEN</tt></td>
 
<td>No</td>
 
<td>No</td>
 
</tr>
 
</tr>
 
<tr>
 
<tr>
 
<td>'''<tt>strategy</tt>'''</td>
 
<td>'''<tt>strategy</tt>'''</td>
<td>By default, EclipseLink persistence provider chooses the type of primary key generator that is most appropriate for the underlying database.<br>If you feel that another generator type is more appropriate for your database or application, set the value of this attribute to one of the following enumerated values of the <tt>GenerationType</tt> enumerated type:
+
<td>By default, EclipseLink persistence provider uses a <tt>TABLE</tt> generator.<br>To use another generator type, set the value of this attribute to one of the enumerated values of the <tt>GenerationType</tt> enumerated type.</td>
<ul>
+
<td><tt>TABLE</tt></td>
  <li><tt>AUTO</tt> (default) – specify that EclipseLink persistence provider should choose a primary key generator that is most appropriate for the underlying database.<br /><br />{{EclipseLink_Note|note=By default, EclipseLink chooses the <tt>TABLE</tt> strategy using a table named <tt>SEQ_GEN_TABLE</tt>, with <tt>SEQ_NAME</tt> and <tt>SEQ_COUNT</tt> columns, with <tt>allocationSize</tt> of 50 and <tt>pkColumnValue</tt> of <tt>SEQ_GEN</tt>. The default <tt>SEQUENCE</tt> used is database sequence <tt>SEQ_GEN_SEQUENCE</tt> with <tt>allocationSize</tt> of 50. Note that the database sequence increment must match the allocation size.}}</li>
+
  <li><tt>TABLE</tt> – specify that EclipseLink persistence provider assign primary keys for the entity using an underlying database table to ensure uniqueness (see [[EclipseLink/UserGuide/JPA/Basic JPA Development/Mapping/Entity/TableGenerator|@TableGenerator]]).</li>
+
  <li><tt>SEQUENCE</tt> – specify that EclipseLink persistence provider use a database sequence (see [[EclipseLink/UserGuide/JPA/Basic JPA Development/Mapping/Entity/SequenceGenerator|@SequenceGenerator]]).</li>
+
  <li><tt>IDENTITY</tt> – specify that EclipseLink persistence provider use a database identity column. Setting this value will indicate to the persistence provider that it must reread the inserted row from the table after an insert has occurred. This will allow it to obtain the newly generated identifier from the database and put it into the in-memory entity that was just persisted. The identity must be defined as part of the database schema for the primary key column. Identity generation may not be shared across multiple entity types.<br />
+
{{EclipseLink_Note|note=<tt>IDENTITY</tt> strategy is supported on Sybase, DB2, SQL Server, MySQL, Derby, JavaDB, Informix, and Postgres databases.}}
+
{{EclipseLink_Note|note=There is a difference between using <tt>IDENTITY</tt> and other id generation strategies: the identifier will not be accessible until after the insert has occurred – it is the action of inserting that caused the identifier generation. Due to the fact that insertion of entities is most often deferred until the commit time, the identifier would not be available until after the transaction has been committed.}}
+
{{EclipseLink_Note|note=We do not recommend using the <tt>IDENTITY</tt> strategy for it does not support preallocation.}}</li>
+
</ul>
+
 
+
</td>
+
<td>The type of primary key generator that is most appropriate for the underlying database</td>
+
 
<td>No</td>
 
<td>No</td>
 
</tr>
 
</tr>
 
}}
 
}}
  
 +
====''<tt>GenerationType</tt>''====
 +
The <tt>strategy</tt> of the <tt>GeneratedValue</tt> is defined by the <tt>GenerationType</tt> enumerated type.  The <tt>strategy</tt> defines how the id value should be generated on the database.
 +
By default, EclipseLink chooses the <tt>TABLE</tt> strategy using a table named <tt>SEQUENCE</tt>, with <tt>SEQ_NAME</tt> and <tt>SEQ_COUNT</tt> columns, with <tt>allocationSize</tt> of 50 and <tt>pkColumnValue</tt> of <tt>SEQ_GEN</tt>.
 +
If <tt>SEQUENCE</tt> is used the default database sequence used is named <tt>SEQ_GEN_SEQUENCE</tt> with an <tt>allocationSize</tt> of 50.
  
The following example shows how to use automatic id generation. This will cause EclipseLink persistence provider to create an identifier value and insert it into the <tt>id</tt> field of each <tt>Employee</tt> entity that gets persisted.<br>
+
The following are the enumerated values of the <tt>GenerationType</tt> enumerated type:
 +
<ul>
 +
  <li><tt>AUTO</tt> – specify that EclipseLink persistence provider should choose a primary key generator that is most appropriate for the underlying database.</li>
 +
{{EclipseLink_Note|note=Be careful when using the automatic ID generation: the persistence provider has to pick its own strategy to store the identifiers, but it needs to have a persistent resource, such as a table or a sequence, to do so. The persistence provider cannot always rely upon the database connection that it obtains from the server to have permissions to create a table in the database. This is usually a privileged operation that is often restricted to the DBA. There will need to be a creation phase or schema generation to cause the resource to be created before the <tt>AUTO</tt> strategy can function.}}
 +
 
 +
  <li><tt>TABLE</tt> – specify that EclipseLink persistence provider assign primary keys for the entity using an underlying database table to ensure uniqueness (see [[EclipseLink/UserGuide/JPA/Basic JPA Development/Entities/Ids/TableGenerator|@TableGenerator]]).</li>
 +
 
 +
  <li><tt>SEQUENCE</tt> – specify that EclipseLink persistence provider use a database sequence (see [[EclipseLink/UserGuide/JPA/Basic JPA Development/Entities/Ids/SequenceGenerator|@SequenceGenerator]]).</li>
 +
{{EclipseLink_Note|note=<tt>SEQUENCE</tt> strategy is database specific and not supported on all database. <tt>SEQUENCE</tt> is supported on Oracle, DB2, Derby, JavaDB, Informix, H2, HSQL, MaxDB, Firebird, Symfoware, and Postgres databases.}}
 +
{{EclipseLink_Note|note=For <tt>SEQUENCE</tt> the database sequence <tt>INCREMENT</tt> must match the <tt>allocationSize</tt> which has a default value of 50.}}
 +
 
 +
  <li><tt>IDENTITY</tt> – specify that EclipseLink persistence provider use a database identity column. Setting this value will indicate to the persistence provider that it must select the inserted row's id from the database after an insert has occurred. This will allow it to obtain the newly generated identifier from the database and put it into the in-memory entity that was just persisted. The identity must be defined as part of the database schema for the primary key column. Identity generation may not be shared across multiple entity types.</li>
 +
{{EclipseLink_Note|note=<tt>IDENTITY</tt> strategy is database specific and not supported on all database. <tt>IDENTITY</tt> is supported on Sybase, DB2, SQL Server, MySQL, Derby, JavaDB, Informix, SQL Anywhere, H2, HSQL, Access, and Postgres databases.}}
 +
{{EclipseLink_Note|note=There is a difference between using <tt>IDENTITY</tt> and other id generation strategies: the identifier will not be accessible until after the insert has occurred – it is the action of inserting that caused the identifier generation. Due to the fact that insertion of entities is most often deferred until the commit time, the identifier would not be available until after the transaction has been flushed or committed.}}
 +
{{EclipseLink_Note|note=We do not recommend using the <tt>IDENTITY</tt> strategy for it does not support preallocation.  This affects performance and usability.}}
 +
</ul>
 +
 
 +
 
 +
The following example shows how to use table id generation. This will cause EclipseLink persistence provider to create an identifier value from a sequence table and insert it into the <tt>id</tt> field of each <tt>Employee</tt> entity that gets persisted.<br>
  
 
======''Example: Using @GeneratedValue''======
 
======''Example: Using @GeneratedValue''======
 
<source lang="java">
 
<source lang="java">
@Entity
+
@Entity
public class Employee implements Serializable {
+
public class Employee implements Serializable {
+
 
    @Id
+
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
+
    @GeneratedValue(strategy=GenerationType.TABLE)
    private int id;
+
    private long id;
    ...
+
    ...
}
+
}
 +
</source>
 +
 
 +
======''Example: Using <code><generated-value></code>''======
 +
 
 +
<source lang="xml">
 +
<entity class="Employee">
 +
    <attributes>
 +
        <id name="empID">
 +
            <generated-value strategy="TABLE"/>
 +
        </id>
 +
        ...
 +
    </attributes>
 +
</entity>
 
</source>
 
</source>
 
<br>
 
<br>
{{EclipseLink_Warning|warning=Be careful when using the automatic ID generation: the persistence provider has to pick its own strategy to store the identifiers, but it needs to have a persistent resource, such as a table or a sequence, to do so. The persistence provider cannot always rely upon the database connection that it obtains from the server to have permissions to create a table in the database. This is usually a privileged operation that is often restricted to the DBA. There will need to be a creation phase or schema generation to cause the resource to be created before the <tt>AUTO</tt> strategy can function.}}
 
  
 +
==Advanced Identity Generation==
 +
EclipseLink provides extensions for other methods of id generation.  Using a <code>SessionCustomizer</code> you can make use of the EclipseLink native API to define advanced or custom sequencing.  The native API defines several <code>Sequence</code> objects that can be registered by name with the EclipseLink <code>Session</code>.  Any <code>@GeneratedValue</code> using the same name will use this custom sequence.  The native API defines <code>QuerySequence</code>, <code>NativeSequence</code>, <code>TableSequence</code>, and <code>UnaryTableSequence</code>.  A <code>QuerySequence</code> can be used to use native SQL or a stored procedure call to allocate the id.  <code>UnaryTableSequence</code> can be used to allocate an id from a single column sequence table.
  
 +
See [[EclipseLink/Examples/JPA/CustomSequencing|CustomSequencing]] for an example of using custom sequencing to define a UUI generated id.
  
 +
It is also possible to generate the value for an <code>Id</code> using the <code>prePersist</code> event, or through triggers when using the Oracle database platform.  See [[EclipseLink/UserGuide/JPA/Advanced_JPA_Development/Returning|Returning]].
 +
 +
======''Example: Using a SessionCustomizer to configure a sequence stored procedure''======
 +
<source lang="java">
 +
public class SequenceCustomizer implements SessionCustomizer {
 +
 +
    public void customize(Session session) {
 +
        StoredProcedureCall call = new StoredProcedureCall();
 +
        call.setProcedureName("SP_ALLOCATE_EMP_ID");
 +
        call.addNamedOutputArgument("ID", "ID", Long.class);
 +
        QuerySequence sequence = new QuerySequence("employee-sequence");
 +
        sequence.setSelectQuery(new ValueReadQuery(call));
 +
        session.getLogin().addSequence(sequence);
 +
    }
 +
}
 +
</source>
 +
 +
==Accessing Generated Values at Runtime==
 +
EclipseLink allows for a generated id value to be accessed at runtime through using the <code>Session.getNextSequenceNumberValue()</code> API.
 +
If the id value has already been assign to an object, EclipseLink will not re-assign the value, so it is possible for the application to assign an id value before calling <code>persist</code>.
 +
 +
======''Example: Using the <code>Session</code> API to access a generated id value at runtime''======
 +
<source lang="java">
 +
long id = em.unwrap(Session.class).getNextSequenceNumberValue(Employee.class).longValue();
 +
</source>
  
 
{{EclipseLink_JPA
 
{{EclipseLink_JPA
|previous=[[EclipseLink/UserGuide/JPA/Basic JPA Development/Mapping/Entity/EmbeddedId|@EmbeddedId]]
+
|previous=[[EclipseLink/UserGuide/JPA/Basic_JPA_Development/Entities/Ids/EmbeddedId|@EmbeddedId]]
|next=    [[EclipseLink/UserGuide/JPA/Basic JPA Development/Mapping/Entity/TableGenerator|@TableGenerator]]
+
|next=    [[EclipseLink/UserGuide/JPA/Basic_JPA_Development/Entities/Ids/TableGenerator|@TableGenerator]]
|up=      [[EclipseLink/UserGuide/JPA/Basic JPA Development/Mapping/Entity|Entity]]
+
|up=      [[EclipseLink/UserGuide/JPA/Basic_JPA_Development/Entities/Creating_and_Configuring_Entities|Configuring Entities]]
 
|version=2.2.0 DRAFT}}
 
|version=2.2.0 DRAFT}}

Latest revision as of 09:12, 22 June 2011

EclipseLink JPA

Contents

[edit] @GeneratedValue

Use the @GeneratedValue annotation or <generated-value> XML element to enable the EclipseLink persistence provider to generate unique identifiers for entity primary keys (see @Id).

Elug javaspec icon.gif

For more information, see Section 11.1.17 "GeneratedValue Annotation" in the JPA Specification.

Use the @GeneratedValue annotation to:

  • Override the type of identity value generation selected by the persistence provider for your database if you feel another generator type is more appropriate for your database or application.
  • Override the generator name to reference your own customized SequenceGenerator or TableGenerator.

The @GeneratedValue annotation has the following attributes:

@GeneratedValue Attributes
Attribute Description Default Required?
generator The name of the SequenceGenerator or TableGenerator object use for this generated value.

If no generator is defined for this name, a generator is defaulted. For a SEQUENCE generator the name becomes the name of the database sequence object.

For a TABLE generator the name becomes the value for the sequence row in the sequence table.
SEQ_GEN No
strategy By default, EclipseLink persistence provider uses a TABLE generator.
To use another generator type, set the value of this attribute to one of the enumerated values of the GenerationType enumerated type.
TABLE No

[edit] GenerationType

The strategy of the GeneratedValue is defined by the GenerationType enumerated type. The strategy defines how the id value should be generated on the database. By default, EclipseLink chooses the TABLE strategy using a table named SEQUENCE, with SEQ_NAME and SEQ_COUNT columns, with allocationSize of 50 and pkColumnValue of SEQ_GEN. If SEQUENCE is used the default database sequence used is named SEQ_GEN_SEQUENCE with an allocationSize of 50.

The following are the enumerated values of the GenerationType enumerated type:

  • AUTO – specify that EclipseLink persistence provider should choose a primary key generator that is most appropriate for the underlying database.
  • Elug note icon.png

    Note: Be careful when using the automatic ID generation: the persistence provider has to pick its own strategy to store the identifiers, but it needs to have a persistent resource, such as a table or a sequence, to do so. The persistence provider cannot always rely upon the database connection that it obtains from the server to have permissions to create a table in the database. This is usually a privileged operation that is often restricted to the DBA. There will need to be a creation phase or schema generation to cause the resource to be created before the AUTO strategy can function.

  • TABLE – specify that EclipseLink persistence provider assign primary keys for the entity using an underlying database table to ensure uniqueness (see @TableGenerator).
  • SEQUENCE – specify that EclipseLink persistence provider use a database sequence (see @SequenceGenerator).
  • Elug note icon.png

    Note: SEQUENCE strategy is database specific and not supported on all database. SEQUENCE is supported on Oracle, DB2, Derby, JavaDB, Informix, H2, HSQL, MaxDB, Firebird, Symfoware, and Postgres databases.

    Elug note icon.png

    Note: For SEQUENCE the database sequence INCREMENT must match the allocationSize which has a default value of 50.

  • IDENTITY – specify that EclipseLink persistence provider use a database identity column. Setting this value will indicate to the persistence provider that it must select the inserted row's id from the database after an insert has occurred. This will allow it to obtain the newly generated identifier from the database and put it into the in-memory entity that was just persisted. The identity must be defined as part of the database schema for the primary key column. Identity generation may not be shared across multiple entity types.
  • Elug note icon.png

    Note: IDENTITY strategy is database specific and not supported on all database. IDENTITY is supported on Sybase, DB2, SQL Server, MySQL, Derby, JavaDB, Informix, SQL Anywhere, H2, HSQL, Access, and Postgres databases.

    Elug note icon.png

    Note: There is a difference between using IDENTITY and other id generation strategies: the identifier will not be accessible until after the insert has occurred – it is the action of inserting that caused the identifier generation. Due to the fact that insertion of entities is most often deferred until the commit time, the identifier would not be available until after the transaction has been flushed or committed.

    Elug note icon.png

    Note: We do not recommend using the IDENTITY strategy for it does not support preallocation. This affects performance and usability.


The following example shows how to use table id generation. This will cause EclipseLink persistence provider to create an identifier value from a sequence table and insert it into the id field of each Employee entity that gets persisted.

[edit] Example: Using @GeneratedValue
@Entity
public class Employee implements Serializable {
 
    @Id
    @GeneratedValue(strategy=GenerationType.TABLE)
    private long id;
    ...
}
[edit] Example: Using <generated-value>
<entity class="Employee">
    <attributes>
        <id name="empID">
            <generated-value strategy="TABLE"/>
        </id>
        ...
    </attributes>
</entity>


[edit] Advanced Identity Generation

EclipseLink provides extensions for other methods of id generation. Using a SessionCustomizer you can make use of the EclipseLink native API to define advanced or custom sequencing. The native API defines several Sequence objects that can be registered by name with the EclipseLink Session. Any @GeneratedValue using the same name will use this custom sequence. The native API defines QuerySequence, NativeSequence, TableSequence, and UnaryTableSequence. A QuerySequence can be used to use native SQL or a stored procedure call to allocate the id. UnaryTableSequence can be used to allocate an id from a single column sequence table.

See CustomSequencing for an example of using custom sequencing to define a UUI generated id.

It is also possible to generate the value for an Id using the prePersist event, or through triggers when using the Oracle database platform. See Returning.

[edit] Example: Using a SessionCustomizer to configure a sequence stored procedure
public class SequenceCustomizer implements SessionCustomizer {
 
    public void customize(Session session) {
        StoredProcedureCall call = new StoredProcedureCall();
        call.setProcedureName("SP_ALLOCATE_EMP_ID");
        call.addNamedOutputArgument("ID", "ID", Long.class);
        QuerySequence sequence = new QuerySequence("employee-sequence");
        sequence.setSelectQuery(new ValueReadQuery(call));
        session.getLogin().addSequence(sequence);
    }
}

[edit] Accessing Generated Values at Runtime

EclipseLink allows for a generated id value to be accessed at runtime through using the Session.getNextSequenceNumberValue() API. If the id value has already been assign to an object, EclipseLink will not re-assign the value, so it is possible for the application to assign an id value before calling persist.

[edit] Example: Using the Session API to access a generated id value at runtime
long id = em.unwrap(Session.class).getNextSequenceNumberValue(Employee.class).longValue();

Eclipselink-logo.gif
Version: 2.2.0 DRAFT
Other versions...