Kodo supports both datastore and application JDO identity types, including single field identity. See Section 4.5, “JDO Identity” in the JDO Overview for coverage of the JDO identity types.
The JPA specification requires you to declare one or more identity fields in your persistent classes, as with JDO's application identity type. Kodo fully supports application identity for JPA entities; however, Kodo also allows you to use datastore identity in your entities. To use datastore identity, simply do not declare any primary key fields. Kodo will use a surrogate database key to track the identity of your objects.
You can control how your JPA datastore identity value is generated
through Kodo's
org.apache.openjpa.persistence.DataStoreId
class
annotation. This annotation has strategy
and
generator
properties that mirror the same-named
properties on the standard javax.persistence.GeneratedValue
annotation described in
Section 5.2.2, “Id” of the JPA Overview.
The functionality of Kodo's DataStoreId
annotation is also analogous to JDO's standard
datastore-identity
mapping element, described in
Section 15.5, “Datastore Identity” of the JDO Overview.
To retrieve the identity value of a datastore identity entity, use the
OpenJPAEntityManager.getObjectId (Object entity)
method. See
Section 9.2.2, “OpenJPAEntityManager”
for more information on the OpenJPAEntityManager
.
Example 5.4. JPA Datastore Identity Metadata
import org.apache.openjpa.persistence.*; @Entity @DataStoreId public class LineItem { ... no @Id fields declared ... }
Internally, Kodo uses the public
kodo.util.Id
class for datastore identity objects. When
writing Kodo plugins, you can manipulate datastore identity objects
by casting them to this class. You can also create your own
Id
instances and pass them to any internal
Kodo method that expects an identity object.
In JPA, you will never see Id
instances
directly. Instead, calling OpenJPAEntityManager.getObjectId
on a datastore identity object will return the
Long
surrogate primary key value for that
object. You can then use this value in calls to
EntityManager.find
for subsequent lookups
of the same record.
In JDO, calling JDOHelper.getObjectId
or
PersistenceManager.getObjectId
on a
persistent object with datastore identity will return an
Id
instance. Remember, however, that datastore
identity in JDO is meant to be opaque; if you find yourself having
to use the Id
class often, it may be a sign
that you should be using application identity.
You can also use any Number
in Kodo JDO to
represent a datastore identity primary key value. The
PersistenceManager.newObjectIdInstance(Class, Object)
method will return an Id
instance when
passed a datastore identity persistent class and a
Number
representing a primary key value.
And the PersistenceManager.getObjectById(Class, Object)
method allows you to look up a datastore identity
instance given its class and Number
primary
key. The JDO specification intended these methods for single field
identity key values, but in Kodo they work for datastore
identity values as well.
If you choose to use application identity, you may want to take advantage of Kodo JPA/JDO's application identity tool. The application identity tool generates Java code implementing the identity class for any persistent type using application identity. The code satisfies all the requirements the specification places on identity classes. You can use it as-is, or simply use it as a starting point, editing it to meet your needs.
Before you can run the application identity tool on a persistent class, the class must be compiled and must have complete metadata. All primary key fields must be marked as such in the metadata.
In JPA metadata, do not attempt to specify the
@IdClass
annotation unless you are using the
application identity tool to overwrite an existing identity class.
Attempting to set the value of the @IdClass
to
a non-existent class will prevent your persistent class from
compiling. Instead, use the -name
or
-suffix
options described below to tell Kodo
what name to give your generated identity class. Once the
application identity tool has generated the class code, you can
set the @IdClass
annotation.
In JDO metadata, set the class' objectid-class
attribute to the desired name of the generated object identity
class.
The application identity tool can be invoked via the included
appidtool
shell/bat script or via its Java class,
kodo.enhance.ApplicationIdTool
.
Note | |
---|---|
Section 14.1.3, “Application Identity Tool Ant Task” describes the application identity tool's Ant task. |
Example 5.5. Using the Application Identity Tool
appidtool -s Id Magazine.java
appidtool package.jdo
The application identity tool accepts the standard set of command-line arguments defined by the configuration framework (see Section 2.3, “Command Line Configuration”), including code formatting flags described in Section 2.3.1, “Code Formatting”. It also accepts the following arguments:
-directory/-d <output directory>
:
Path to the output directory. If the directory does not
match the generated oid class' package, the package
structure will be created beneath the directory. If not
specified, the tool will first try to find the directory of
the .java
file for the
persistence-capable class, and failing that will use the
current directory.
-ignoreErrors/-i <true/t | false/f>
: If false
, an exception will
be thrown if the tool is run on any class that does not
use application identity, or is not the base class in the
inheritance hierarchy (recall that subclasses never define
the application identity class; they inherit it from their
persistent superclass).
-token/-t <token>
: The token
to use to separate stringified primary key values in the
string form of the object id. This option is only used
if you have multiple primary key fields. It defaults to
"::".
-name/-n <id class name>
: The name
of the identity class to generate. If this option is
specified, you must run the tool on exactly one class.
If the class metadata already names an object id class,
this option is ignored. If the name is not fully qualified,
the persistent class' package is prepended to form the
qualified name.
-suffix/-s <id class suffix>
: A
string to suffix each persistent class name with to form
the identity class name. This option is overridden by
-name
or by any object id class specified
in metadata.
Each additional argument to the tool must be one of the following:
The full name of a persistent class.
The .java file for a persistent class.
The .class
file of a persistent class.
A .jdo
metadata file. The tool will
run on each class listed in the metadata.
If you do not supply any arguments to the tool, it will act on the classes in your persistent classes list (see Section 5.1, “Persistent Class List”).
If you do not have a persistent classes list, the tool will scan
your classpath for directories containing .jdo
files, and run on all classes listed in those files.
Section 5.2.3, “Generated Value” explains how to use JPA's
IDENTITY
generation type.
Section 15.5, “Datastore Identity” and
Section 15.11.3, “Automatic Values” of the JDO
Overview explain how to use JDO's autoassign
and identity
strategies for datastore identity
and field values. However, here are some additional
caveats you should be aware of when using these strategies:
Your database must support auto-increment / identity columns, or some equivalent (see Section 4.4.3, “OracleDictionary Properties” for how to configure a combination of triggers and sequences to fake auto-increment support in Oracle).
Auto-increment / identity columns must be an integer or long integer type.
Databases support auto-increment / identity columns to varying degrees. Some do not support them at all. Others only allow a single such column per table, and require that it be the primary key column. More lenient databases may allow non-primary key auto-increment columns, and may allow more than one per table. See your database documentation for details.
Statements inserting into tables with auto-increment / identity columns cannot be batched. After each insert, Kodo must go back to the database to retrieve the last inserted auto-increment value to set back in the persistent object. This can have a negative impact on performance.