Tuesday, June 9, 2015

SEQUENCE

Generators

  • AUTO
  • SEQUENCE
  • TABLE
  • IDENTITY
  • UUID
  • CUSTOM
  • NONE

Here is a summary : the list of possible generation strategies:

AUTO (default): Tells Doctrine to pick the strategy that is preferred by the used database platform. The preferred strategies are IDENTITY for MySQL, SQLite and MsSQL and SEQUENCE for Oracle and PostgreSQL. This strategy provides full portability.

SEQUENCE: Tells Doctrine to use a database sequence for ID generation. This strategy does currently not provide full portability. Sequences are supported by Oracle and PostgreSql.

IDENTITY: Tells Doctrine to use special identity columns in the database that generate a value on insertion of a row. This strategy does currently not provide full portability and is supported by the following platforms:

  • MySQL/SQLite => AUTO_INCREMENT
  • MSSQL => IDENTITY
  • PostgreSQL => SERIAL

TABLE: Tells Doctrine to use a separate table for ID generation. This strategy provides full portability. This strategy is not yet implemented!

NONE: Tells Doctrine that the identifiers are assigned, and thus generated, by your code. The assignment must take place before a new entity is passed to EntityManager#persist. NONE is the same as leaving off the @GeneratedValue entirely.

An object id (OID) is something that uniquely identifies an object. Within a VM this is typically the object's pointer. In a relational database table, a row is uniquely identified in its table by its primary key. When persisting objects to a database you need a unique identifier for the objects, this allows you to query the object, define relationships to the object, and update and delete the object. In JPA the object id is defined through the @Id annotation or element and should correspond to the primary key of the object's table.

Example id annotation

     ...
@Entity
public class Employee {
     @Id
     private long id;
     ...
}

Example id XML

<entity name="Employee" class="org.acme.Employee" access="FIELD">
       <attributes>
         <id name="id"/>
       </attributes>
<entity/>

Sequencing

An object id can either be a natural id or a generated id. A natural id is one that occurs in the object and has some meaning in the application. Examples of natural ids include email addresses, phone numbers, and social insurance numbers. A generated id (also known as a surrogate id) is one that is generated by the system. A sequence number in JPA is a sequential id generated by the JPA implementation and automatically assigned to new objects. The benefits of using sequence numbers are that they are guaranteed to be unique, allow all other data of the object to change, are efficient values for querying and indexes, and can be efficiently assigned. The main issue with natural ids is that everything always changes at some point; even a person's social insurance number can change. Natural ids can also make querying, foreign keys and indexing less efficient in the database.

In JPA an @Id can be easily assigned a generated sequence number through the @GeneratedValue annotation, or element.

Example generated id annotation

     ...
@Entity
public class Employee {
     @Id
     @GeneratedValue
     private long id;
     ...
}

Example id XML

<entity name="Employee" class="org.acme.Employee" access="FIELD">
       <attributes>
         <id name="id">
            <generated-value/>
         </id>
       </attributes>
<entity/>

Sequence Strategies

There are several strategies for generating unique ids. Some strategies are database agnostic and others make use of built-in databases support.

JPA provides support for several strategies for id generation defined through the GenerationType enum values: TABLE, SEQUENCE and IDENTITY. The choice of which sequence strategy to use is important as it affects performance, concurrency and portability.

1. Sequence objects

Sequence objects use special database objects to generate ids. Sequence objects are only supported in some databases, such as Oracle, DB2, and Postgres. Usually, a SEQUENCE object has a name, an INCREMENT, and other database object settings. Each time the .NEXTVAL is selected the sequence is incremented by the INCREMENT.

Sequence objects provide the optimal sequencing option, as they are the most efficient and have the best concurrency, however they are the least portable as most databases do not support them. Sequence objects support sequence preallocation through setting the INCREMENT on the database sequence object to the sequence preallocation size.

In JPA the @SequenceGenerator annotation or element is used to define a sequence object. The SequenceGenerator defines a sequenceName for the name of the database sequence object, and an allocationSize for the sequence preallocation size or sequence object INCREMENT.

Example sequence generator annotation

     ...
@Entity
public class Employee {
     @Id
     @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="EMP_SEQ")
     @SequenceGenerator(name="EMP_SEQ", sequenceName="EMP_SEQ", allocationSize=100)
     private long id;
     ...
}

Example sequence generator XML

<entity name="Employee" class="org.acme.Employee" access="FIELD">
       <attributes>
          <id name="id">
             <generated-value strategy="SEQUENCE" generator="EMP_SEQ"/>
             <sequence-generator name="EMP_SEQ" sequence-name="EMP_SEQ" allocation-size="100"/>
          </id>
       </attributes>
<entity/>
More on SEQUENCING here

No comments:

Post a Comment