JDO2 provides a way for users to specify that a field will be persisted
serialised
. This is of use, for example, to
collections/maps/arrays which typically are stored using join tables or foreign-keys to other records. By
specifying that a field is serialised a column will be added to store that field and the field will be serialised
into it.
JDO2's definition of serialising encompasses several types of fields. These are described below
Perhaps the most important thing to bear in mind when deciding to serialise a field is that that object must implement
java.io.Serializable
.
Collections are usually persisted by way of either a
join table
, or by use of a
foreign-key
in the element table. In some situations it is required to store the whole collection in a single column
in the table of the class being persisted. This prohibits the querying of such a collection, but will
persist the collection in a single statement. Let's take an example. We have the following classes
and we want the
animals
collection to be serialised into a single column in the table
storing the
Farm
class, so we define our MetaData like this
<class name="Farm" table="FARM">
<datastore-identity column="ID"/>
<field name="name" column="NAME"/>
<field name="animals" serialized="true">
<collection element-type="Animal"/>
<column name="ANIMALS"/>
</field>
</class>
<class name="Animal">
<field name="name"/>
<field name="type"/>
</class>
So we make use of the
serialized
attribute of <field>. This specification results in a table
like this
Provisos to bear in mind are
-
Queries cannot be performed on collections stored as serialised.
There are some other combinations of MetaData tags that result in serialising of the whole collection in
the same way. These are as follows
-
Collection of non-
PersistenceCapable
elements, and no <join> is specified.
Since the elements don't have a table of their own, the only option is to serialise the whole collection
and it appears as a single BLOB field in the table of the main class.
-
Collection of
PersistenceCapable
elements, with "embedded-element" set to
true
and no <join> is specified.
Since the elements are embedded and there is no join table, then the whole collection is serialised as above.
See also :-
Collections are usually persisted by way of either a
join table
, or by use of a
foreign-key
in the element table. In some situations you may want to serialise the element into a single column in the join
table. Let's take an example. We have the same classes as in the previous case and we want the
animals
collection to be stored in a join table, and the element serialised into a single column storing the "Animal"
object. We define our MetaData like this
<class name="Farm" table="FARM">
<datastore-identity column="ID"/>
<field name="name">
<column name="NAME"/>
</field>
<field name="animals" table="FARM_ANIMALS">
<collection element-type="Animal" serialised-element="true"/>
<join column="FARM_ID_OID"/>
</field>
</class>
<class name="Animal">
<field name="name"/>
<field name="type"/>
</class>
So we make use of the
serialized-element
attribute of <collection>. This specification results in tables
like this
Provisos to bear in mind are
-
Queries cannot be performed on collection elements stored as serialised.
See also :-
Maps are usually persisted by way of a
join table
, or very occasionaly using a
foreign-key
in the value table. In some situations it is required to store the whole map in a single column
in the table of the class being persisted. This prohibits the querying of such a map, but will
persist the map in a single statement. Let's take an example. We have the following classes
and we want the
children
map to be serialised into a single column in the table
storing the
ClassRoom
class, so we define our MetaData like this
<class name="ClassRoom">
<field name="level">
<column name="LEVEL"/>
</field>
<field name="children" serialized="true">
<map key-type="java.lang.String" value-type="Child"/>
<column name="CHILDREN"/>
</field>
</class>
<class name="Child"/>
So we make use of the
serialized
attribute of <field>. This specification results in a table
like this
Provisos to bear in mind are
-
Queries cannot be performed on maps stored as serialised.
There are some other combinations of MetaData tags that result in serialising of the whole map in
the same way. These are as follows
-
Map<non-
PersistenceCapable
, non-
PersistenceCapable
>, and no <join> is specified.
Since the keys/values don't have a table of their own, the only option is to serialise the whole map
and it appears as a single BLOB field in the table of the main class.
-
Map<non-
PersistenceCapable
,
PersistenceCapable
>, with "embedded-value" set to
true
and no <join> is specified.
Since the keys/values are embedded and there is no join table,
then the whole map is serialised as above.
See also :-
Maps are usually persisted by way of a
join table
, or very occasionaly using a
foreign-key
in the value table. In the join table case you have the option of serialising the keys and/or the values
each into a single (BLOB) column in the join table. This is performed in a similar way to serialised
elements for collections, but this time using the "serialized-key", "serialized-value" attributes.
We take the example in the previous section, with "a classroom of children" and the children stored in
a map field. This time we want to serialise the child object into the join table of the map
<class name="ClassRoom">
<field name="level">
<column name="LEVEL"/>
</field>
<field name="children" table="CLASS_CHILDREN">
<map key-type="java.lang.String" value-type="Child" serialized-value="true"/>
<join column="CLASSROOM_ID"/>
<key column="ALIAS"/>
<value column="CHILD"/>
</field>
</class>
<class name="Child"/>
So we make use of the
serialized-value
attribute of <map>. This results in a schema like this
Provisos to bear in mind are
-
Queries cannot be performed on map keys/values stored as serialised.
See also :-
A field that is a
PersistenceCapable
object is typically stored as a foreign-key relation between
the container object and the contained object. In some situations it is not necessary that the contained
object has an identity of its own, and for efficiency of access the contained object is required to be
stored in a BLOB column in the containing object's datastore table. Let's take an example. We have the following
classes
and we want the
teacher
object to be serialised into a single column in the table
storing the
ClassRoom
class, so we define our MetaData like this
<class name="ClassRoom">
<field name="level">
<column name="LEVEL"/>
</field>
<field name="teacher" serialized="true">
<column name="TEACHER"/>
</field>
</class>
So we make use of the
serialized
attribute of <field>. This specification results in a table
like this
Provisos to bear in mind are
-
Queries cannot be performed on PersistenceCapable objects stored as serialised.
A reference (Interface/Object) field is typically stored as a foreign-key relation between the container object and the
contained implementation of the reference. In some situations it is not necessary that the contained object has an
identity of its own, and for efficiency of access the contained object is required to be stored in a BLOB column in the
containing object's datastore table. Let's take an example using an interface field. We have the following classes
and we want the
teacher
object to be serialised into a single column in the table
storing the
ClassRoom
class, so we define our MetaData like this
<class name="ClassRoom">
<field name="level">
<column name="LEVEL"/>
</field>
<field name="teacher" serialized="true">
<column name="TEACHER"/>
</field>
</class>
<class name="Teacher">
</class>
So we make use of the
serialized
attribute of <field>. This specification results in a table
like this
Provisos to bear in mind are
-
Queries cannot be performed on Reference (Interface/Object) fields stored as serialised.
See also :-