![]() | ![]() |
![]() |
| Project | Ver 1.1 | Ver 1.2 | JDO | JPA | Guides | Tools |
| 1.1 | Preparation | O/R Mapping | Runtime | Extensions | Developer |
By specifying that your class will use either datastore identity or application identity, you specified whether the identity of the object is stored in a hidden field, or stored in one (or more) of the classes fields. This section allows you further control over the identity assignment, allowing you to define the means of assignment of identity. In addition, the same mechanism can be used to populate values in a field where you want them auto-generating, even if the field isn't used for identities. JPOX supports the automatic generation of primary key values for datastore identity and for application identity as mandated by the JDO 2 specification. Fields can have their values generated using the value-strategy facility. The methods for generating unique identifiers are in most cases datastore dependent, but database neutral methods are also available. You should always choose the most appropriate for the datastore being used. With all of the different strategies for generating values shown below, all are specified in the same way. For datastore identity you will specify a MetaData element of the form
<class name="MyClass" identity-type="datastore">
<datastore-identity strategy="..."/>
...
</class>For application identity or field value population you will specify a MetaData element of the form
<class name="MyClass" identity-type="application">
<field value-strategy="..."/>
...
</class>There are many different strategies available with JDO2 and JPOX.
These are described below. See also :-
With this strategy JPOX will choose the most appropriate strategy for the datastore being used. If you also specify the 'sequence' name attribute and the datastore supports sequences then "sequence" strategy would be used. Otherwise it will always choose "increment" strategy.
A sequence is a user-defined database function that generates a sequence of unique numeric ids. The unique identifier value returned from the database is translated to a java type: java.lang.Long. JPOX supports sequences for the following databases:
To configure a class to use either of these generation methods with datastore identity you simply add this to the class' JDO Meta-Data
<class name="myclass" ... >
<datastore-identity strategy="sequence" sequence="YOUR_SEQUENCE_NAME"/>
...
</class>You replace "YOUR_SEQUENCE_NAME" with your sequence name. To configure a class to use either of these generation methods using application identity you would add the following to the class' JDO Meta-Data
<class name="myclass" ... >
<field name="myfield" primary-key="true" value-strategy="sequence" sequence="YOUR_SEQUENCE_NAME"/>
...
</class>If the sequence does not yet exist in the database at the time JPOX needs a new unique identifier, a new sequence is created in the database based on the JDO Meta-Data configuration. Additional properties for configuring sequences are set in the JDO Meta-Data, see the available properties below. Unsupported properties by a database are silently ignored by JPOX.
This value generator will generate values unique across different JVMs
Auto-increment/identity/serial are primary key columns that are populated when a row is inserted in the table. These use the databases own keywords on table creation and so rely on having the table structure either created by JPOX or having the column with the necessary keyword. JPOX supports auto-increment/identity/serial keys for many databases including :
For a class using datastore identity you need to set the strategy attribute. You can configure the JDO Meta-Data for the class something like this (replacing 'myclass' with your class name) :
<class name="myclass">
<datastore-identity strategy="identity"/>
...
</class>For a class using application identity you need to set the value-strategy attribute on the primary key field. You can configure the JDO Meta-Data for the class something like this (replacing 'myclass' and 'myfield' with your class and field names) :
<class name="myclass" identity-type="application" objectid-class="myprimarykeyclass">
<field name="myfield" primary-key="true" value-strategy="identity"/<
...
</class>Please be aware that if you have an inheritance tree with the base class defined as using "identity" then the column definition for the PK of the base table will be defined as "AUTO_INCREMENT" or "IDENTITY" or "SERIAL" (dependent on the RDBMS) and all subtables will NOT have this identifier added to their PK column definitions. This is because the identities are assigned in the base table (since all objects will have an entry in the base table). This value generator will generate values unique across different JVMs
This method is database neutral and uses a sequence table that holds an incrementing sequence value. The unique identifier value returned from the database is translated to a java type: java.lang.Long. This strategy will work with any datastore. This method require a sequence table in the database and creates one if doesn't exist. To configure a datastore identity class to use this generation method you simply add this to the classes JDO Meta-Data.
<class name="myclass" ... >
<datastore-identity strategy="increment"/>
...
</class>To configure an application identity class to use this generation method you simply add this to the class' JDO Meta-Data. If your class is in an inheritance tree you should define this for the base class only.
<class name="myclass" ... >
<field name="myfield" primary-key="true" value-strategy="increment"/>
...
</class>Additional properties for configuring this generator are set in the JDO Meta-Data, see the available properties below. Unsupported properties are silently ignored by JPOX.
This value generator will generate values unique across different JVMs (from JPOX 1.1.3)
This generator creates identities with 16 characters in string format. The identity contains the IP address of the local machine where JPOX is running, as well as other necessary components to provide uniqueness across time. This generator can be used in concurrent applications. It is especially useful in situations where large numbers of transactions within a certain amount of time have to be made, and the additional overhead of synchronizing the concurrent creation of unique identifiers through the database would break performance limits. It doesn't require datastore access to generate the identities and so has performance benefits over some of the other generators. For a class using datastore identity you need to add metadata something like the following
<class name="myclass" ... >
<datastore-identity strategy="uuid-string"/>
...
</class>To configure an application identity class to use this generation method you simply add this to the class' JDO Meta-Data.
<class name="myclass" ... >
<field name="myfield" primary-key="true" value-strategy="uuid-string"/>
...
</class>
This generator creates identities with 32 characters in hexadecimal format. The identity contains the IP address of the local machine where JPOX is running, as well as other necessary components to provide uniqueness across time. This generator can be used in concurrent applications. It is especially useful in situations where large numbers of transactions within a certain amount of time have to be made, and the additional overhead of synchronizing the concurrent creation of unique identifiers through the database would break performance limits. It doesn't require datastore access to generate the identities and so has performance benefits over some of the other generators. For a class using datastore identity you need to add metadata something like the following
<class name="myclass" ... >
<datastore-identity strategy="uuid-hex"/>
...
</class>To configure an application identity class to use this generation method you simply add this to the class' JDO Meta-Data.
<class name="myclass" ... >
<field name="myfield" primary-key="true" value-strategy="uuid-hex"/>
...
</class>
![]() This method is database neutral and uses the "select max(column) from table" + 1 strategy to create unique ids. The unique identifier value returned from the database is translated to a java type: java.lang.Long. It is however not recommended by JPOX since it makes a DB call for every record to be inserted and hence is inefficient. Each DB call will run a scan in all table contents causing contention and locks in the table. We recommend the use of either Sequence or Identity based value generators (see below) - which you use would depend on your RDBMS. For a class using datastore identity you need to add metadata something like the following
<class name="myclass" ... >
<datastore-identity strategy="max"/>
...
</class>To configure an application identity class to use this generation method you simply add this to the class' JDO Meta-Data.
<class name="myclass" ... >
<field name="myfield" primary-key="true" value-strategy="max"/>
...
</class>This value generator will NOT guarantee to generate values unique across different JVMs. This is because it will select the "max+1" and before creating the record another thread may come in and insert one.
![]() This generator uses a Java implementation of DCE UUIDs to create unique identifiers without the overhead of additional database transactions or even an open database connection. The identifiers are Strings of the form "LLLLLLLL-MMMM-HHHH-CCCC-NNNNNNNNNNNN" where 'L', 'M', 'H', 'C' and 'N' are the DCE UUID fields named time low, time mid, time high, clock sequence and node. This generator can be used in concurrent applications. It is especially useful in situations where large numbers of transactions within a certain amount of time have to be made, and the additional overhead of synchronizing the concurrent creation of unique identifiers through the database would break performance limits. For a class using datastore identity you need to add metadata something like the following
<class name="myclass" ... >
<datastore-identity strategy="auid"/>
...
</class>To configure an application identity class to use this generation method you simply add this to the class' JDO Meta-Data.
<class name="myclass" ... >
<field name="myfield" primary-key="true" value-strategy="auid"/>
...
</class>This value generator will generate values unique across different JVMs
![]() This section describes how to use the JPOX Poid API for generating unique keys for objects outside the JPOX (JDO) runtime. JPOX defines a framework for identity generation and provides many builtin strategies for identities. You can make use of the same strategies described above but for generating identities manually for your own use. The process is described below The JPOX POID API revolves around 2 classes. The entry point for retrieving generators is the PoidManager. This manages the appropriate PoidGenerator classes. Poid generators maintain a block of cached ids in memory which avoid reading the database each time it needs a new unique id. Caching a block of unique ids provides you the best performance but can cause "holes" in the sequence of ids for the stored objects in the database. Let's take an example. Here we want to obtain an identity using the SequenceTablePoidGenerator ("increment" above). This stores the identities in a datastore table. We want to generate an identity using this. Here is what we add to our code
PersistenceManagerImpl pm = (PersistenceManagerImpl) ... // cast your pm to impl ;
// Obtain a PoidManager
PoidManager mgr = new PoidManager();
// Obtain a PoidGenerator of the required type
Properties properties = new Properties();
properties.setProperty("table-name", "GLOBAL"); // Use a global sequence number (for all tables)
PoidGenerator generator = mgr.createPoidGenerator(pm.getClassLoaderResolver(), "MyGenerator",
"org.jpox.store.rdbms.poid.SequenceTablePoidGenerator", props, pm.getStoreManager(),
new PoidConnectionProvider()
{
RDBMSManager rdbmsManager = null;
Connection con;
public Object retrieveConnection()
{
rdbmsManager = (RDBMSManager) pm.getStoreManager();
try
{
// important to use TRANSACTION_NONE like JPOX does
con = (Connection)rdbmsManager.getConnection(Connection.TRANSACTION_NONE);;
return con;
}
catch (SQLException e)
{
logger.error("Failed to obtain new DB connection for identity generation!");
throw new RuntimeException(e);
}
}
public void releaseConnection()
{
try
{
rdbmsManager.closeConnection(con);
}
catch (SQLException e)
{
logger.error("Failed to close DB connection for identity generation!");
throw new RuntimeException(e);
}
finally
{
rdbmsManager = null;
}
}
});
// Retrieve the next identity using this strategy
Long identifier = (Long)generator.next();Some Poid Generators are specific to RDBMS datastores, and some are generic, so bear this in mind when selecting and adding your own. |