By specifying that your class will use either datastore identity or application identity, you specified who would have control over the identity assignment process. This section allows you further control over the identity assignment, allowing you to define the means of assignment of identity. JPOX supports the automatic generation of primary keys for datastore identity, mandated by the JDO specification, and for application identity. Generating unique identifiers for application identity is only supported for non-composed keys. The methods for generating unique identifiers are in most of times database dependent, but database neutral methods are also available. Database dependent methods provides better performance compared to database neutral methods.
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 is the default generator used by JPOX for datastore identity since it will work on any datastore. This method requires a sequence table in the database and creates one if doesn't exist. To configure an application identity class to use this generation method you simply add this to the class' JDO Meta-Data. The SequenceTablePoidGenerator will be used by default.
<class name="Component" ... >
<extension vendor-name="jpox" key="use-poid-generator" value="true"/>
...
</class>
For a class using datastore identity you need to do nothing to use this. It is the default. 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 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 AutoIncrement based Poid generators (see below) - which you use would depend on your RDBMS. To configure an application identity class to use this generation method you simply add this to the class' JDO Meta-Data.
<class name="Component" ... >
<extension vendor-name="jpox" key="use-poid-generator" value="true"/>
<extension vendor-name="jpox" key="poid-class-generator" value="org.jpox.poid.MaxPoidGenerator"/>
...
</class>
For a class using datastore identity you need to add metadata something like the following
<class name="Component" ... >
<extension vendor-name="jpox" key="poid-class-generator" value="org.jpox.poid.MaxPoidGenerator"/>
...
</class>
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. To configure an application identity class to use this generation method you simply add this to the class' JDO Meta-Data.
<class name="Component" ... >
<extension vendor-name="jpox" key="use-poid-generator" value="true"/>
<extension vendor-name="jpox" key="poid-class-generator" value="org.jpox.poid.AUIDPoidGenerator"/>
...
</class>
This generator is not currently available for datastore identity.
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 you simply add this to the class' JDO Meta-Data
<class name="Component" ... >
<extension vendor-name="jpox" key="use-poid-generator" value="true"/>
<extension vendor-name="jpox" key="poid-class-generator" value="org.jpox.poid.OracleSequencePoidGenerator"/>
<extension vendor-name="jpox" key="sequence-name" value="YOUR_SEQUENCE_NAME"/>
...
</class>
where you replace "YOUR_SEQUENCE_NAME" with your sequence name. The same applies to Postgresql, replacing the poid-class-generator value with org.jpox.poid.PostgresqlSequencePoidGenerator. 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.
Auto-increment are primary key columns that are populated when a row is inserted in the table. To use auto-increment with JPOX, you need to add the extension key-auto-increment to the JDO Meta-Data file. JPOX supports auto-increment keys for the following databases:
For a class using datastore identity you can configure the JDO Meta-Data for the class something like this (replacing 'myclass' with your class name) :
<class name="myclass">
<extension vendor-name="jpox" key="key-auto-increment" value="true"/>
...
</class>
For a class using application identity 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"<
<extesion vendor-name="jpox" key="key-auto-increment" value="true"/>
</field>
...
</class>
If JPOX doesn't provide support to your id generator, you can create your own id generator. TODO describe how to create custom id generators
This section describes how to use the JPOX Poid API for generating unique keys for objects outside the JPOX (JDO) runtime. JPOX provides with its distribution pre-built id generators that be can used in the most common scenarios, but if the provided id generators does not meet your requirements, you can create your own id generator. The POID API works with properties for configuring id generators. Each id generator can have a set of required properties to work, and missing or wrong provided properties may lead to errors difficult to diagnose. 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. If "holes" in your sequence is not a problem for your application, adequate the cached block of ids size to a similar number of new objects your application creates by session.
The MaxPoidGenerator is designed to be used with Relational Databases using the "select max(column) from table" + 1 strategy to generate unique ids for objects.
It is not recommended to use this generator in concurrent applications. Usage :
Connection conn = ....
Properties = new Properties();
properties.put("COLUMN_NAME","myColumn");
properties.put("TABLE_NAME","myTable");
PoidManager poidManager = new PoidManager();
poidManager.setPoidGeneratorName("org.jpox.poid.MaxPoidGenerator");
poidManager.setProperties(properties);
poidManager.setConnection(conn);
Poid poid = poidManager.getPoid();
Long identifier = (Long)poid.getOid();
This is a sequence generator to be used with Oracle sequences.
Usage :
Connection conn = ....
Properties = new Properties();
properties.put("SEQUENCE","mySequence");
PoidManager poidManager = new PoidManager();
poidManager.setPoidGeneratorName("org.jpox.poid.OracleSequencePoidGenerator");
poidManager.setProperties(properties);
poidManager.setConnection(conn);
Poid poid = poidManager.getPoid();
Long identifier = (Long) poid.getOid();
This is a sequence generator to be used with PostgreSQL sequences.
Usage :
Connection conn = ....
Properties = new Properties();
properties.put("SEQUENCE","mySequence");
PoidManager poidManager = new PoidManager();
poidManager.setPoidGeneratorName("org.jpox.poid.PostgresqlSequencePoidGenerator");
poidManager.setProperties(properties);
poidManager.setConnection(conn);
Poid poid = poidManager.getPoid();
Long identifier = (Long) poid.getOid();
|