JDO : Array fields

JDO allows implementations to optionally support the persistence of arrays. DataNucleus provides full support for arrays in similar ways that collections are supported. DataNucleus supports persisting arrays as

  • Single Column - the array is byte-streamed into a single column in the table of the containing object.
  • Serialised - the array is serialised into single column in the table of the containing object.
  • Using a Join Table - where the array relation is persisted into the join table, with foreign-key links to an element table where the elements of the array are persistable
  • Using a Foreign-Key in the element - only available where the array is of a persistable type
JDO has no simple way of detecting changes to an arrays contents. To update an array you must either
  • replace the array field with the new array value
  • update the array element and then call JDOHelper.makeDirty(obj, "fieldName");

Single Column Arrays

Let's suppose you have a class something like this

So we have an Account and it has a number of permissions, each expressed as a byte. We want to persist the permissions in a single-column into the table of the account (but we don't want them serialised). We then define MetaData something like this

<class name="Account" identity-type="datastore">
    <field name="firstName">
        <column name="FIRST_NAME" length="100" jdbc-type="VARCHAR"/>
    </field>
    <field name="lastName">
        <column column="LAST_NAME" length="100" jdbc-type="VARCHAR"/>
    </field>
    <field name="permissions" column="PERMISSIONS"/>
</class>

You could have added <array> to be explicit but the type of the field is an array, and the type declaration also defines the component type so nothing more is needed. This results in a datastore schema as follows

DataNucleus supports persistence of the following array types in this way : boolean[], byte[], char[], double[], float[], int[], long[], short[], Boolean[], Byte[], Character[], Double[], Float[], Integer[], Long[], Short[], BigDecimal[], BigInteger[]

See also :-


Serialised Arrays

Let's suppose you have a class something like this

So we have an Account and it has a number of permissions, each expressed as a byte. We want to persist the permissions as serialised into the table of the account. We then define MetaData something like this

<class name="Account" identity-type="datastore">
    <field name="firstName">
        <column name="FIRST_NAME" length="100" jdbc-type="VARCHAR"/>
    </field>
    <field name="lastName">
        <column column="LAST_NAME" length="100" jdbc-type="VARCHAR"/>
    </field>
    <field name="permissions" serialized="true" column="PERMISSIONS"/>
</class>

That is, you define the field as serialized. To define arrays of short, long, int, or indeed any other supported array type you would do the same as above. This results in a datastore schema as follows

DataNucleus supports persistence of many array types in this way, including : boolean[], byte[], char[], double[], float[], int[], long[], short[], Boolean[], Byte[], Character[], Double[], Float[], Integer[], Long[], Short[], BigDecimal[], BigInteger[], String[], java.util.Date[], java.util.Locale[]

See also :-


Arrays persisted into Join Tables

DataNucleus will support arrays persisted into a join table. Let's take the example above and make the "permission" a class in its own right, so we have

So an Account has an array of Permissions, and both of these objects are persistable. We want to persist the relationship using a join table. We define the MetaData as follows

<class name="Account" table="ACCOUNT">
    <field name="firstName">
        <column name="FIRST_NAME" length="100" jdbc-type="VARCHAR"/>
    </field>
    <field name="lastName">
        <column column="LAST_NAME" length="100" jdbc-type="VARCHAR"/>
    </field>
    <field name="permissions" table="ACCOUNT_PERMISSIONS">
        <array/>
        <join column="ACCOUNT_ID"/>
        <element column="PERMISSION_ID"/>
        <order column="PERMISSION_ORDER_IDX"/>
    </field>
</class>
<class name="Permission" table="PERMISSION">
    <field name="name"/>
</class>

This results in a datastore schema as follows


See also :-


Arrays persisted using Foreign-Keys

DataNucleus will support arrays persisted via a foreign-key in the element table. This is only applicable when the array is of a persistable type. Let's take the same example above. So we have

So an Account has an array of Permissions, and both of these objects are persistable. We want to persist the relationship using a foreign-key in the table for the Permission class. We define the MetaData as follows

<class name="Account" table="ACCOUNT">
    <field name="firstName">
        <column name="FIRST_NAME" length="100" jdbc-type="VARCHAR"/>
    </field>
    <field name="lastName">
        <column column="LAST_NAME" length="100" jdbc-type="VARCHAR"/>
    </field>
    <field name="permissions">
        <array/>
        <element column="ACCOUNT_ID"/>
        <order column="ACCOUNT_PERMISSION_ORDER_IDX"/>
    </field>
</class>
<class name="Permission" table="PERMISSION">
    <field name="name"/>
</class>

This results in a datastore schema as follows


See also :-