5. Generators
Prev | Chapter 13. Mapping Metadata | Next

## 5. Generators

One aspect of identity mapping not covered in the previous section is JPA's ability to automatically assign a value to your numeric identity fields using generators. We discussed the available generator types in Section 2.3, “ Id ”. Now we show you how to define named generators.

### 5.1. Sequence Generator

Most databases allow you to create native sequences. These are database structures that generate increasing numeric values. The `SequenceGenerator` annotation represents a named database sequence. You can place the annotation on any package, entity class, persistent field declaration (if your entity uses field access), or getter method for a persistent property (if your entity uses property access). `SequenceGenerator` has the following properties:

- `String name`: The generator name. This property is required.

- `String sequenceName`: The name of the database sequence. If you do not specify the database sequence, your vendor will choose an appropriate default.

- `int initialValue`: The initial sequence value.

- `int allocationSize`: The number of values to allocate in memory for each trip to the database. Allocating values in memory allows the JPA runtime to avoid accessing the database for every sequence request. This number also specifies the amount that the sequence value is incremented each time the sequence is accessed. Defaults to 50.

- `String schema`: The sequence's schema. If you do not name a schema, JPA uses the default schema for the database connection.

### Note

OpenJPA allows you to use one of OpenJPA's built-in generator implementations in the `sequenceName` property. You can also set the `sequenceName` to `system` to use the system sequence defined by the `openjpa.Sequence` configuration property. See the Reference Guide's Section 6, “ Generators ” for details.

The XML element for a sequence generator is `sequence-generator` . Its attributes mirror the above annotation's properties:

- `name`

- `sequence-name`

- `initial-value`

- `allocation-size`

- `schema`

To use a sequence generator, set your `GeneratedValue` annotation's `strategy` property to `GenerationType.SEQUENCE`, and its `generator` property to the sequence generator's declared name. Or equivalently, set your `generated-value` XML element's `strategy` attribute to `SEQUENCE` and its `generator` attribute to the generator name.

### 5.2. Table Generator

A `TableGenerator` refers to a database table used to store increasing sequence values for one or more entities. As with `SequenceGenerator`, you can place the `TableGenerator` annotation on any package, entity class, persistent field declaration (if your entity uses field access), or getter method for a persistent property (if your entity uses property access). `TableGenerator` has the following properties:

- `String name`: The generator name. This property is required.

- `String table`: The name of the generator table. If left unspecified, your vendor will choose a default table.

- `String schema`: The named table's schema.

- `String catalog`: The named table's catalog.

- `String pkColumnName`: The name of the primary key column in the generator table. If unspecified, your implementation will choose a default.

- `String valueColumnName`: The name of the column that holds the sequence value. If unspecified, your implementation will choose a default.

- `String pkColumnValue`: The primary key column value of the row in the generator table holding this sequence value. You can use the same generator table for multiple logical sequences by supplying different `pkColumnValue` s. If you do not specify a value, the implementation will supply a default.

- `int initialValue`: The value of the generator's first issued number.

- `int allocationSize`: The number of values to allocate in memory for each trip to the database. Allocating values in memory allows the JPA runtime to avoid accessing the database for every sequence request. This number also specifies the amount that the sequence value is incremented each time the generator table is updated. Defaults to 50.

The XML equivalent is the `table-generator` element. This element's attributes correspond exactly to the above annotation's properties:

- `name`

- `table`

- `schema`

- `catalog`

- `pk-column-name`

- `value-column-name`

- `pk-column-value`

- `initial-value`

- `allocation-size`

To use a table generator, set your `GeneratedValue` annotation's `strategy` property to `GenerationType.TABLE`, and its `generator` property to the table generator's declared name. Or equivalently, set your `generated-value` XML element's `strategy` attribute to `TABLE` and its `generator` attribute to the generator name.

### 5.3. Example

Let's take advantage of generators in our entity model. Here are our updated mappings.

Example 13.4. Generator Mapping

    package org.mag;

    @Entity
    @IdClass(Magazine.MagazineId.class)
    @Table(name="MAG")
    public class Magazine {

        @Column(length=9)
        @Id private String isbn;
        @Id private String title;

        ...

        public static class MagazineId {
            ...
        }
    }

    @Entity
    @Table(name="ART", uniqueConstraints=@Unique(columnNames="TITLE"))
    @SequenceGenerator(name="ArticleSeq", sequenceName="ART_SEQ")
    public class Article {

        @Id
        @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="ArticleSeq")
        private long id;

        ...
    }

    package org.mag.pub;

    @Entity
    @Table(name="COMP")
    public class Company {

        @Column(name="CID")
        @Id private long id;

        ...
    }

    @Entity
    @Table(name="AUTH")
    public class Author {

        @Id
        @GeneratedValue(strategy=GenerationType.TABLE, generator="AuthorGen")
        @TableGenerator(name="AuthorGen", table="AUTH_GEN", pkColumnName="PK",
            valueColumnName="AID")
        @Column(name="AID", columnDefinition="INTEGER64")
        private long id;

        ...
    }

    @Embeddable
    public class Address {
        ...
    }

    package org.mag.subscribe;

    @MappedSuperclass
    public abstract class Document {

        @Id
        @GeneratedValue(generate=GenerationType.IDENTITY)
        private long id;

        ...
    }

    @Entity
    @Table(schema="CNTRCT")
    public class Contract
        extends Document {

        ...
    }

    @Entity
    @Table(name="SUB", schema="CNTRCT")
    public class Subscription {

        @Id
        @GeneratedValue(strategy=GenerationType.IDENTITY)
        private long id;

        ...

        @Entity
        @Table(name="LINE_ITEM", schema="CNTRCT")
        public static class LineItem
            extends Contract {
            ...
        }
    }

    @Entity(name="Lifetime")
    public class LifetimeSubscription
        extends Subscription {
        ...
    }

    @Entity(name="Trial")
    public class TrialSubscription
        extends Subscription {
        ...
    }

The same metadata for `Article` and `Author` expressed in XML form:

    <entity class="org.mag.Article">
        <table name="ART">
            <unique-constraint>
                <column-name>TITLE</column-name>
            </unique-constraint>
        </table>
        <sequence-generator name="ArticleSeq" sequence-name="ART_SEQ"/>
        <attributes>
            <id name="id">
                <generated-value strategy="SEQUENCE" generator="ArticleSeq"/>
            </id>
            ...
        </attributes>
    </entity>
    <entity class="org.mag.pub.Author">
        <table name="AUTH"/>
        <attributes>
            <id name="id">
                <column name="AID" column-definition="INTEGER64"/>
                <generated-value strategy="TABLE" generator="AuthorGen"/>
                <table-generator name="AuthorGen" table="AUTH_GEN"
                    pk-column-name="PK" value-column-name="AID"/>
            </id>
            ...
        </attributes>
    </entity>

Prev | Up | Next
4. Identity Mapping | Home | 6. Inheritance