blob: df7a777b0793a1552a6fd32130a1cdd4037bee93 [file] [log] [blame]
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>5.&nbsp; Generators</title><link rel="stylesheet" href="css/docbook.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.72.0"><link rel="start" href="manual.html" title="Apache OpenJPA 1.2 User's Guide"><link rel="up" href="jpa_overview_mapping.html" title="Chapter&nbsp;12.&nbsp; Mapping Metadata"><link rel="prev" href="jpa_overview_mapping_id.html" title="4.&nbsp; Identity Mapping"><link rel="next" href="jpa_overview_mapping_inher.html" title="6.&nbsp; Inheritance"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">5.&nbsp;
Generators
</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="jpa_overview_mapping_id.html">Prev</a>&nbsp;</td><th width="60%" align="center">Chapter&nbsp;12.&nbsp;
Mapping Metadata
</th><td width="20%" align="right">&nbsp;<a accesskey="n" href="jpa_overview_mapping_inher.html">Next</a></td></tr></table><hr></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="jpa_overview_mapping_sequence"></a>5.&nbsp;
Generators
</h2></div></div></div><div class="toc"><dl><dt><span class="section"><a href="jpa_overview_mapping_sequence.html#jpa_overview_mapping_sequence_seqgen">5.1.
Sequence Generator
</a></span></dt><dt><span class="section"><a href="jpa_overview_mapping_sequence.html#jpa_overview_mapping_sequence_tablegen">5.2.
TableGenerator
</a></span></dt><dt><span class="section"><a href="jpa_overview_mapping_sequence.html#jpa_overview_mapping_sequence_genex">5.3.
Example
</a></span></dt></dl></div><a class="indexterm" name="d0e9959"></a><a class="indexterm" name="d0e9964"></a><p>
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
<span class="emphasis"><em>generators</em></span>. We discussed the available generator types in
<a href="jpa_overview_meta_field.html#jpa_overview_meta_id" title="2.2.&nbsp; Id">Section&nbsp;2.2, &#8220;
Id
&#8221;</a>. Now we show you how to define
named generators.
</p><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="jpa_overview_mapping_sequence_seqgen"></a>5.1.&nbsp;
Sequence Generator
</h3></div></div></div><a class="indexterm" name="d0e9983"></a><a class="indexterm" name="d0e9988"></a><p>
Most databases allow you to create native sequences. These are database
structures that generate increasing numeric values. The <code class="classname">
SequenceGenerator</code> 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). <code class="classname">
SequenceGenerator</code> has the following properties:
</p><div class="itemizedlist"><ul type="disc"><li><p>
<a class="indexterm" name="d0e10003"></a>
<code class="literal">String name</code>: The generator name. This property is required.
</p></li><li><p>
<a class="indexterm" name="d0e10015"></a>
<code class="literal">String sequenceName</code>: The name of the database sequence. If
you do not specify the database sequence, your vendor will choose an appropriate
default.
</p></li><li><p>
<a class="indexterm" name="d0e10027"></a>
<code class="literal">int initialValue</code>: The initial sequence value.
</p></li><li><p>
<a class="indexterm" name="d0e10039"></a>
<code class="literal">int allocationSize</code>: 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.
</p></li></ul></div><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
OpenJPA allows you to use one of OpenJPA's built-in generator
implementations in the <code class="literal">sequenceName</code> property. You can also
set the <code class="literal">sequenceName</code> to <code class="literal">system</code> to use the
system sequence defined by the <a href="ref_guide_conf_openjpa.html#openjpa.Sequence" title="5.59.&nbsp; openjpa.Sequence"><code class="literal">
openjpa.Sequence</code></a> configuration property. See the Reference
Guide's <a href="ref_guide_sequence.html" title="6.&nbsp; Generators">Section&nbsp;6, &#8220;
Generators
&#8221;</a> for details.
</p></div><p>
The XML element for a sequence generator is <code class="literal">sequence-generator
</code>. Its attributes mirror the above annotation's properties:
</p><div class="itemizedlist"><ul type="disc"><li><p>
<code class="literal">name</code>
</p></li><li><p>
<code class="literal">sequence-name</code>
</p></li><li><p>
<code class="literal">initial-value</code>
</p></li><li><p>
<code class="literal">allocation-size</code>
</p></li></ul></div><p>
To use a sequence generator, set your <code class="classname">GeneratedValue</code>
annotation's <code class="literal">strategy</code> property to <code class="literal">
GenerationType.SEQUENCE</code>, and its <code class="literal">generator</code> property
to the sequence generator's declared name. Or equivalently, set your <code class="literal">
generated-value</code> XML element's <code class="literal">strategy</code> attribute to
<code class="literal">SEQUENCE</code> and its <code class="literal">generator</code> attribute to
the generator name.
</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="jpa_overview_mapping_sequence_tablegen"></a>5.2.&nbsp;
TableGenerator
</h3></div></div></div><a class="indexterm" name="d0e10125"></a><a class="indexterm" name="d0e10130"></a><p>
A <code class="classname">TableGenerator</code> refers to a database table used to store
increasing sequence values for one or more entities. As with <code class="classname">
SequenceGenerator</code>, you can place the <code class="classname">TableGenerator
</code> 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). <code class="classname">
TableGenerator</code> has the following properties:
</p><div class="itemizedlist"><ul type="disc"><li><p>
<a class="indexterm" name="d0e10151"></a>
<code class="literal">String name</code>: The generator name. This property is required.
</p></li><li><p>
<a class="indexterm" name="d0e10163"></a>
<code class="literal">String table</code>: The name of the generator table. If left
unspecified, your vendor will choose a default table.
</p></li><li><p>
<a class="indexterm" name="d0e10175"></a>
<code class="literal">String schema</code>: The named table's schema.
</p></li><li><p>
<a class="indexterm" name="d0e10187"></a>
<code class="literal">String catalog</code>: The named table's catalog.
</p></li><li><p>
<a class="indexterm" name="d0e10199"></a>
<code class="literal">String pkColumnName</code>: The name of the primary key column in
the generator table. If unspecified, your implementation will choose a default.
</p></li><li><p>
<a class="indexterm" name="d0e10211"></a>
<code class="literal">String valueColumnName</code>: The name of the column that holds
the sequence value. If unspecified, your implementation will choose a default.
</p></li><li><p>
<a class="indexterm" name="d0e10223"></a>
<code class="literal">String pkColumnValue</code>: 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 <code class="literal">
pkColumnValue</code> s. If you do not specify a value, the implementation
will supply a default.
</p></li><li><p>
<a class="indexterm" name="d0e10238"></a>
<code class="literal">int initialValue</code>: The value of the generator's first issued
number.
</p></li><li><p>
<a class="indexterm" name="d0e10250"></a>
<code class="literal">int allocationSize</code>: 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.
</p></li></ul></div><p>
The XML equivalent is the <code class="literal">table-generator</code> element. This
element's attributes correspond exactly to the above annotation's properties:
</p><div class="itemizedlist"><ul type="disc"><li><p>
<code class="literal">name</code>
</p></li><li><p>
<code class="literal">table</code>
</p></li><li><p>
<code class="literal">schema</code>
</p></li><li><p>
<code class="literal">catalog</code>
</p></li><li><p>
<code class="literal">pk-column-name</code>
</p></li><li><p>
<code class="literal">value-column-name</code>
</p></li><li><p>
<code class="literal">pk-column-value</code>
</p></li><li><p>
<code class="literal">initial-value</code>
</p></li><li><p>
<code class="literal">allocation-size</code>
</p></li></ul></div><p>
To use a table generator, set your <code class="classname">GeneratedValue</code>
annotation's <code class="literal">strategy</code> property to <code class="literal">
GenerationType.TABLE</code>, and its <code class="literal">generator</code> property to
the table generator's declared name. Or equivalently, set your <code class="literal">
generated-value</code> XML element's <code class="literal">strategy</code> attribute to
<code class="literal">TABLE</code> and its <code class="literal">generator</code> attribute to the
generator name.
</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="jpa_overview_mapping_sequence_genex"></a>5.3.&nbsp;
Example
</h3></div></div></div><p>
Let's take advantage of generators in our entity model. Here are our updated
mappings.
</p><div class="example"><a name="jpa_overview_mapping_sequenceex"></a><p class="title"><b>Example&nbsp;12.4.&nbsp;
Generator Mapping
</b></p><div class="example-contents"><pre class="programlisting">
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 {
...
}
</pre><p>
The same metadata for <code class="literal">Article</code> and <code class="literal">Author</code>
expressed in XML form:
</p><pre class="programlisting">
&lt;entity class="org.mag.Article"&gt;
&lt;table name="ART"&gt;
&lt;unique-constraint&gt;
&lt;column-name&gt;TITLE&lt;/column-name&gt;
&lt;/unique-constraint&gt;
&lt;/table&gt;
&lt;sequence-generator name="ArticleSeq" sequence-name="ART_SEQ"/&gt;
&lt;attributes&gt;
&lt;id name="id"&gt;
&lt;generated-value strategy="SEQUENCE" generator="ArticleSeq"/&gt;
&lt;/id&gt;
...
&lt;/attributes&gt;
&lt;/entity&gt;
&lt;entity class="org.mag.pub.Author"&gt;
&lt;table name="AUTH"/&gt;
&lt;attributes&gt;
&lt;id name="id"&gt;
&lt;column name="AID" column-definition="INTEGER64"/&gt;
&lt;generated-value strategy="TABLE" generator="AuthorGen"/&gt;
&lt;table-generator name="AuthorGen" table="AUTH_GEN"
pk-column-name="PK" value-column-name="AID"/&gt;
&lt;/id&gt;
...
&lt;/attributes&gt;
&lt;/entity&gt;
</pre></div></div><br class="example-break"></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="jpa_overview_mapping_id.html">Prev</a>&nbsp;</td><td width="20%" align="center"><a accesskey="u" href="jpa_overview_mapping.html">Up</a></td><td width="40%" align="right">&nbsp;<a accesskey="n" href="jpa_overview_mapping_inher.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">4.&nbsp;
Identity Mapping
&nbsp;</td><td width="20%" align="center"><a accesskey="h" href="manual.html">Home</a></td><td width="40%" align="right" valign="top">&nbsp;6.&nbsp;
Inheritance
</td></tr></table></div></body></html>