JPA : Array Fields

JPA defines support the persistence of arrays but only arrays of byte[], Byte[], char[], Character[]. DataNucleus supports all types of arrays, as follows

  • Single Column - the array is byte-streamed into a single column in the table of the containing object.
  • JoinTable (Non-Entity) - the array is stored in a "join" table, with a column in that table storing each element of the array
  • JoinTable (Entity) - the array is stored via a "join" table, with FK across to the element Entity.
  • ForeignKey (Entity) - the array is stored via a FK in the element Entity.

Single Column Arrays (serialised)

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. We then define MetaData something like this

<entity class="Account">
    <table name="ACCOUNT"/>
    <attributes>
        ...
        <basic name="permissions">
            <column name="PERMISSIONS"/>
            <lob/>
        </basic>
        ...
    </attributes>
</entity>

This results in a datastore schema as follows

See also :-


Arrays stored in join table

If you want an array of non-persistable objects be stored in a "join" table, you can follow this example. We have an Account that stores a Collection of addresses. These addresses are simply Strings. We define the annotations like this

@Entity
public class Account
{
    ...

    @ElementCollection
    @CollectionTable(name="ACCOUNT_ADDRESSES")
    String[] addresses;
}

or using XML metadata

<entity class="mydomain.Account">
    <attributes>
        ...
        <element-collection name="addresses">
            <collection-table name="ACCOUNT_ADDRESSES"/>
        </element-collection>
    </attributes>
</entity>

In the datastore the following is created

Use @Column on the field/method to define the column details of the element in the join table.

Arrays of Entity persisted into Join Tables

DataNucleus will support arrays persisted into a join table. Let's take the example of a class Account with an array of Permission objects, so we have

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

@Entity
public class Account
{
    ...

    @OneToMany
    @JoinTable(name="ACCOUNT_PERMISSIONS", joinColumns={@Column(name="ACCOUNT_ID")}, inverseJoinColumns={@Column(name="PERMISSION_ID")})
    @OrderColumn(name="PERMISSION_ORDER_IDX")
    String[] addresses;
}

@Entity
public class Permission
{
    ...
}

or using XML metadata

<entity class="mydomain.Account">
    <attributes>
        ...
        <one-to-many name="permissions">
            <join-table name="ACCOUNT_PERMISSIONS">
                <join-column name="ACCOUNT_ID"/>
                <inverse-join-column name="PERMISSION_ID"/>
            </join-table>
            <order-column name="PERMISSION_ORDER_IDX"/>
        </one-to-many>
    </attributes>
</entity>
<entity name="Permission" table="PERMISSION">
</entity>

This results in a datastore schema as follows


Arrays of Entity 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

@Entity
public class Account
{
    ...

    @OneToMany
    @JoinColumn(name="ACCOUNT_ID")
    @OrderColumn(name="PERMISSION_ORDER_IDX")
    String[] addresses;
}

@Entity
public class Permission
{
    ...
}

or using XML metadata

<entity class="mydomain.Account">
    <attributes>
        ...
        <one-to-many name="permissions">
            <join-column name="ACCOUNT_ID"/>
            <order-column name="PERMISSION_ORDER_IDX"/>
        </one-to-many>
    </attributes>
</entity>
<entity name="Permission" table="PERMISSION">
</entity>

This results in a datastore schema as follows