JDO has several types of identity. You must select the type of identity to use for each persistent class. An identity class represents an identity value, and its form depends on the type of identity. Each persistent class has an associated identity class that represents a unique identity value for each persistent instance. If you have two instances of identity classes for two persistent instances, they will compare equal if and only if the persistent instances have the same JDO identity. JDO provides methods to map between a persistent instance and its associated identity.
JDO defines three types of identity:
The identity is managed by the JDO implementation or the datastore and is not associated with the values of any fields in the instance.
The identity is managed by the application, and its uniqueness is enforced by the JDO implementation or datastore. The identity is composed of one or more fields of the class, referred to as the primary-key fields. The composite value of the primary-key fields must uniquely identify each persistent instance in the datastore. You must define an application identity class with fields that correspond, in name and type, to the primary-key fields in the persistent class.
Some datastores do not support a unique identifier for some of their data. For example, a log file or a table in a relational database may not have a primary-key constraint. For the JDO implementation to manage instances that do not have a durable identity, nondurable identity provides a unique identity for each instance while it is in the JVM; but this identity is not preserved or used in the datastore.
JDO uses these three different types of identity to model existing datastores. Many relational databases use application-visible primary-key columns in which the values of the columns represent real-world concepts. For example, a purchase order's line item table contains an purchase-order number and a line number as a composite primary key, and these columns have significance in the application domain. Most object databases provide identity for persistent instances that do not depend on application-visible values. In order to support natural mappings for both of these styles of identity, JDO provides both application identity and datastore identity.
There are other cases, primarily from the relational-database domain, where there is no identity associated with a row in a table. For example, there is no natural key for a log-file entry, and although there may be queryable columns, there is no uniqueness requirement. Support for these kinds of tables is provided by nondurable identity.
Each type of identity is an optional feature in JDO, but a JDO implementation must support either datastore or application identity and may support both. They have the following property names:
javax.jdo.option.DatastoreIdentity
javax.jdo.option.ApplicationIdentity
javax.jdo.option.NondurableIdentity
You can call supportedOptions( ), defined in PersistenceManagerFactory, to determine which types of identity your implementation supports.
You need to select an identity type for each persistent class. You declare the identity type in the metadata using the identity-type attribute in the class element for the persistent class. It can be given one of the following values:
"datastore"
"application"
"nondurable"
The application can explicitly specify a value for identity-type or let it have a default value. If you decide to use application identity for a persistent class, you need to define an application identity class and specify it in the metadata in the class element's objectid-class attribute. Some implementations can generate this class for you. Only application identity uses the objectid-class attribute. So, if you specify the objectid-class attribute for a persistent class, its identity-type attribute defaults to "application"; otherwise, it defaults to "datastore". Furthermore, the identity type you select for the least-derived persistent class in an inheritance hierarchy is used as the identity type for all the persistent classes in the inheritance hierarchy. Once you have enhanced a persistent class, its identity type is fixed.
Table 10-1 summarizes which type of identity you will get based on the values you provide for these metadata attributes. The MyApplId class denotes an application identity class that you have defined.
Value of identity-type |
Value of objectid-class |
Identity type used for the class |
---|---|---|
No value provided |
No value provided |
Datastore identity |
No value provided |
"MyApplId" |
Application identity |
"datastore" |
No value provided |
Datastore identity |
"datastore" |
"MyApplId" |
Error |
"application" |
No value provided |
Error |
"application" |
"MyApplId" |
Application identity |
"nondurable" |
No value provided |
Nondurable identity |
"nondurable" |
"MyApplId" |
Error |
If you have a class C that extends class B, where B has a value specified for the objectid-class attribute, class C must also use application identity and must either use class B's objectid-class (if the objectid-class is concrete) or define its own objectid-class that extends B's objectid-class. You never specify the objectid-class attribute for subclasses of concrete classes.
Every persistent class has an associated identity class that is used to represent the unique identity of each persistent instance. The JDO implementation defines the classes used to represent datastore and nondurable identity. The implementation may use the same identity class for multiple persistent classes, or a different identity class for each persistent class. On the other hand, when you use application identity, you must define an application identity class yourself.
Every persistent instance has a unique identity value, which can be represented by an instance of the identity class. You can acquire a copy of the identity instance associated with a persistent instance; you can save it, retrieve it later from durable storage (by serialization or some other technique), and use it to obtain a reference to the same persistent instance. The JDO implementation does not necessarily maintain an instantiation of the identity instance in the cache for each persistent instance in the cache, but it can construct an instance for use by your application.
When you make an instance persistent via makePersistent( ), the instance is assigned an identity. If the metadata states that the instance's class has an identity type that the implementation does not support, a JDOUserException is thrown for that instance. The enhancer in some implementations may also produce a warning or error when the class is enhanced if the implementation does not support the identity type.
The identity of a persistent instance is managed by the JDO implementation. For classes with a durable identity (datastore or application identity), each PersistenceManager instance manages at most one instance in the memory cache for a given object in the datastore, regardless of how your application accessed the persistent instance.