One aspect of identity mapping not covered in the previous section is EJB's ability to automatically assign a value to your numeric identity fields using generators. We discussed the available generator types in Section 5.2.2, “Id”. Now we show you how to define named generators.
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 sequenceName
: The name of the
database sequence. If you do not specify the database
sequence, your vendor will choose an appropriate default.
int allocationSize
: Some databases can
pre-allocate groups of sequence values. This allows the
database to service sequence requests from cache, rather
than physically incrementing the sequence with every
request. This allocation size defaults to 50.
Note | |
---|---|
Kodo allows you to use describe one of Kodo's built-in generator
implementations in the |
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
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.
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 table
: The name of the
generator table. If left unspecified, your vendor will
choose a default table.
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 EJB persistence
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.
Let's take advantage of generators in our entity model. Here are our updated mappings.
Example 12.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>