When persisting a class you need to decide how it is to be mapped to the datastore. By this we mean
which fields of the class are persisted. DataNucleus knows how to persist
certain Java types and so you bear this list in mind when deciding which
fields to persist. Also please note that JDO
cannot persist static or final fields
.
Let's take a sample class as an example
public class Hotel
{
private long id; // identity
private String name;
private String address;
private String telephoneNumber;
private int numberOfRooms;
private String hotelNickname;
private Set rooms = new HashSet();
private Manager manager;
...
}
We have a series of fields and we want to persist all fields apart from
hotelNickname
which is of no real use
in our system. In addition, we want our
Hotel
class to be detachable, meaning that we can detach objects of that
type update them in a different part of our system, and the attach them again.
We can define this basic persistence information in 3 ways - with XML MetaData, with
JDK1.5 Annotations or with a mix of MetaData and Annotations.
We show all ways here.
To achieve the above aim we define our Meta-Data like this
<class name="Hotel" detachable="true">
<field name="id" primary-key="true"/>
<field name="name"/>
<field name="address"/>
<field name="telephoneNumber"/>
<field name="numberOfRooms"/>
<field name="hotelNickname" persistence-modifier="none"/>
<field name="rooms">
<collection element-type="Room"/>
</field>
<field name="manager"/>
</class>
Note the following
-
We have identified the
id
field as the primary key. We didn't bother specifying a
Primary Key class since there is only a single PK field.
By doing this we have selected application-identity
-
We have included all fields in the MetaData, although if you look at the Types Guide
you see the column "Persistent?". All "simple" types like String, int are by default persistent and so we could
have omitted these since they are by default going to be persisted.
-
We have used
persistence-modifier
for the
hotelNickname
field to make it non-persistent.
-
Our Set field we have identified the type of the element that it contains. This is compulsory for
collection and map fields. If the field is declared using JDK1.5 generics then you can safely
omit this since all necessary information is in the class declaration.
-
We have added the attribute "detachable" as true for the class.
So it is really very simple. This first step is to define the basic persistence of a class.
If you are using a datastore (such as RDBMS) that requires detailed mapping information then you now need
to proceed to the Schema Mapping Guide. If however you are using
a datastore that doesnt need such information (such as DB4O) then you have defined the persistence of your class.
See also :-
Here we are using JDK1.5 or higher and we annotate the class directly using JDO Annotations
We annotate the class like this
@PersistenceCapable
public class Hotel
{
@PrimaryKey
private long id;
private String name;
private String address;
private String telephoneNumber;
private int numberOfRooms;
@NotPersistent
private String hotelNickname;
@Element(types=org.datanucleus.samples.Room.class)
private Set rooms = new HashSet();
private Manager manager;
...
}
Note that we could have omitted the @Element if we had declared the
rooms
field as
Set<Room>
.
See also :-
If we are using JDK 1.5+ we can take advantage of Annotations, but we want to take into account the disadvantage
of Annotations, namely that we may want to deploy our application to multiple datastores. This means that we would
be extremely unwise to specify ORM information in Annotations. With this in mind we decide that we will specify
just the basic persistence information (which classes/fields are persisted etc) using Annotations, and the remainder
will go in MetaData.
The order of precedence for persistence information is
-
ORM MetaData definition
-
JDO MetaData definition
-
Annotations definition
So anything specified in MetaData will override all Annotations.
With JDO persistence all classes that are persisted have to be identified in MetaData or annotations as
shown above. In addition, if any of your other classes
access the fields of these persistable classes directly
then these other classes should be defined as
PersistenceAware
. You do this as follows
<class name="MyClass" persistence-modifier="persistence-aware"/>
or with annotations
@PersistenceAware
public class MyClass
{
...
}
See also :-
If you are using XML MetaData you can also override the MetaData for fields/properties of
superclasses. You do this by adding an entry for
{class-name}.fieldName
, like this
<class name="Hotel" detachable="true">
...
<field name="HotelSuperclass.someField" default-fetch-group="false"/>
so we have changed the field "someField" specified in the persistent superclass "HotelSuperclass"
to not be part of the DFG.