As you read in the guide for
PersistenceManagerFactory
, to control the
persistence of your objects you will require at least one
PersistenceManagerFactory
.
Once you have obtained this object you then use this to obtain a
PersistenceManager
.
A
PersistenceManager
provides access to the operations for persistence of your objects.
This short guide will demonstrate some of the more common operations.
You obtain a
PersistenceManager
as follows
PersistenceManager pm = pmf.getPersistenceManager();
In general you will be performing all operations on a
PersistenceManager
within a transaction,
whether your transactions are controlled by your J2EE container, by a framework such as Spring, or by
locally defined transactions. In the examples below we will omit the transaction demarcation for
clarity.
A
PersistenceManagerFactory
is designed to be thread-safe.
A
PersistenceManager
is not
The main thing that you will want to do with the data layer of a JDO-enabled application is
persist your objects into the datastore. As we mentioned earlier, a
PersistenceManagerFactory
represents the datastore where the objects will be persisted. So you create a normal Java object
in your application, and you then persist this as follows
This will result in the object being persisted into the datastore, though clearly it will not be
persistent until you commit the transaction. The LifecycleState of the object changes from
Transient
to
PersistentClean
(after makePersistent), to
Hollow
(at commit).
Once you have persisted an object, it has an "identity". This is a unique way of identifying it.
You can obtain the identity by calling
Object id = pm.getObjectId(obj);
So what ? Well the identity can be used to retrieve the object again at some other part in your
application. So you pass the identity into your application, and the user clicks on some button
on a web page and that button corresponds to a particular object identity. You can then go back
to your data layer and retrieve the object as follows
Object obj = pm.getObjectById(id);
A DataNucleus extension is to pass in a String form of the identity to the above method.
It accepts identity strings of the form
-
{fully-qualified-class-name}:{key}
-
{discriminator-name}:{key}
where the
key
is the identity value (datastore-identity) or
the result of PK.toString() (application-identity). So for example we could input
obj = pm.getObjectById("mydomain.MyClass:3");
When you call the method
getObjectById
if an object with that identity is found in the
cache then a call is, by default, made to validate it still exists. You can avoid this call
to the datastore by setting the persistence property
datanucleus.findObject.validateWhenCached
to
false
.
When you need to delete an object that you had previous persisted, deleting it is simple.
Firstly you need to get the object itself, and then delete it as follows
Object obj = pm.getObjectById(id); // Retrieves the object to delete
pm.deletePersistent(obj);
Don't forget that you can also use deletion by query
to delete objects. Alternatively use bulk deletion.
To modify a previously persisted object you only need to enlist the (updated) object in
a transaction and its changes will be propagated to the datastore at commit of the transaction.
Don't forget that you can also use bulk update to update
a group of objects of a type.
You often have a previously persisted object and you want to use it away from the data-access
layer of your application. In this case you want to
detach
the object (and its related
objects) so that they can be passed across to the part of the application that requires it.
To do this you do
Object detachedObj = pm.detachCopy(obj); // Returns a copy of the persisted object, in detached state
The detached object is like the original object except that it has no StateManager connected,
and it stores its JDO identity and version. It retains a list of all fields that are modified
while it is detached. This means that when you want to "attach" it to the data-access layer it
knows what to update.
As an alternative, to make the detachment process transparent, you can set the PMF property
datanucleus.DetachAllOnCommit
to true and when you commit your transaction all objects
enlisted in the transaction will be detached.
You've detached an object (shown above), and have modified it in your application, and you now
want to attach it back to the persistence layer. You do this as follows
Object attachedObj = pm.makePersistent(obj); // Returns a copy of the detached object, in attached state
In the situation where you have an object and you think that its values may have changed in
the datastore you can update its values to the latest using the following
What this will do is as follows
-
Refresh the values of all FetchPlan fields in the object
-
Unload all non-FetchPlan fields in the object
If the object had any changes they will be thrown away by this step, and replaced by
the latest datastore values.