JDO : Versioning of Objects

JDO allows objects of classes to be versioned. The version is typically used as a way of detecting if the object has been updated by another thread or PersistenceManager since retrieval using the current PersistenceManager - for use by Optimistic Transactions. JDO defines several "strategies" for generating the version of an object. The strategy has the following possible values

  • none stores a number like the version-number but will not perform any optimistic checks.
  • version-number stores a number (starting at 1) representing the version of the object.
  • date-time stores a Timestamp representing the time at which the object was last updated. Note that not all RDBMS store milliseconds in a Timestamp!
  • state-image stores a Long value being the hash code of all fields of the object. DataNucleus doesnt currently support this option

Versioning using a surrogate column

JDO2s mechanism for versioning of objects in RDBMS datastores is via a surrogate column in the table of the class. In the MetaData you specify the details of the surrogate column and the strategy to be used. For example

<package name="mydomain">
    <class name="User" table="USER">
        <version strategy="version-number" column="VERSION"/>
        <field name="name" column="NAME"/>
        ...
    </class>
</package>

alternatively using annotations

@PersistenceCapable
@Version(strategy=VersionStrategy.VERSION_NUMBER, column="VERSION")
public class MyClass
{
    ...
}

The specification above will create a table with an additional column called "VERSION" that will store the version of the object.


Versioning using a field of the class

DataNucleus provides a valuable extension to JDO whereby you can have a field of your class store the version of the object. This equates to JPA's versioning process whereby you have to have a field present. To do this lets take a class

public class User
{
    String name;
    ...
    long myVersion;

}

and we want to store the version of the object in the field "myVersion". So we specify the metadata as follows

<package name="mydomain">
    <class name="User" table="USER">
        <version strategy="version-number">
            <extension vendor-name="datanucleus" key="field-name" value="myVersion"/>
        </version>
        <field name="name" column="NAME"/>
        ...
        <field name="myVersion" column="VERSION"/>
    </class>
</package>
                

alternatively using annotations

@PersistenceCapable
@Version(strategy=VersionStrategy.VERSION_NUMBER, column="VERSION",
         extensions={@Extension(vendorName="datanucleus", key="field-name", value="myVersion")})
public class MyClass
{
    protected long myVersion;
    ...
}

and so now objects of our class will have access to the version via the "myVersion" field.