3.8 Deleting an Object
The last basic operation is deletion. Unlike Java, most datastores do not perform automatic garbage collection. Indeed, the semantics of what constitutes garbage when instances are made persistent changes. Just because a persistent object is no longer referenced by any other does not mean that it is garbage. Typically, it can always be retrieved at any time via Query or Extent.
JDO provides a mechanism to explicitly delete persistent objects. The deletePersistent() method on PersistenceManager can be used to permanently remove persistent objects from the datastore.
public void deletePersistent(Object pc)
Of course, the persistent object isn't actually deleted until the transaction is committed. Rather, the JDO implementation marks the persistent object as deleted and, upon commit, requests that the datastore remove all the deleted persistent objects. The following code snippet taken from DeleteExample.java shows how to delete an instance of Author. For simplicity, it assumes that at least one author instance with the specified name is in the datastore:
tx.begin(); Query query = pm.newQuery(Author.class, "name == \"Keiron McCammon\""); Collection result = (Collection) query.execute(); Author author = (Author) result.iterator().next(); query.close(result); pm.deletePersistent(author); tx.commit();
Trying to access the fields of a deleted instance within the same transaction results in JDOUserException being thrown.
After the transaction commits, the in-memory instance reverts to being a normal transient Java object, with its fields reset to their default values. If a rollback is called instead, then the deletion is undone and the in-memory instance reverts to being a "hollow" persistent object again. The following code snippet taken from DeleteWithRollbackExample.java uses a rollback rather than a commit and then validates that the persistent object still exists by printing its name:
pm.deletePersistent(author); tx.rollback(); // rollback() rather than commit() tx.begin(); String name = author.getName(); System.out.println("Author's name is '" + name + "'."); tx.commit();
The output would be as follows:
Author's name is 'Keiron McCammon'.
JDO is unlike a JVM, where garbage collection automatically determines whether an instance is still referenced and, if not, releases it. In JDO it is up to the application to ensure that unwanted persistent objects are deleted from the data-store and that a persistent object being deleted is no longer referenced by another.
Depending on the datastore, it may be possible to define constraints to guard against deleting instances that are still referenced, but this is implementation specific. If a persistent object does reference a previously deleted persistent object, then JDOUserException is thrown if the deleted persistent object is later accessed (because it no longer will be found in the datastore).
There is no equivalent of "persistence by reachability" when deleting. Deleting a persistent object deletes only the specified instance; it does not automatically delete any referenced instances.
It is possible for an application to implement a cascading delete behavior by using the JDO InstanceCallbacks interface and implementing the jdoPreDelete() method to explicitly delete referenced instances. See Chapter 5 for more details.