JDO (Java Data Objects) is a specification for transparent persistence being developed as JSR-000012 in the Java Community Process. Transparent persistence allows developers to store their Java objects in transactional data stores "transparently", meaning that they do not need to explicitly manage the field-by-field storage and retrieval to and from the data store.
Transparency is also a feature of the built-in Java persistence capability known as Serialization. This article will highlight the differences between JDO and Serialization.
Setup: JDO requires that the program acquire a PersistenceManagerFactory instance, either by construction or by lookup from JNDI. The most significant initialization parameter is an absolute or relative file name to use to store the instances, represented by URL:"fostore:relative/path/filename". Serialization requires that the user open an ObjectOutputStream, which for persistence would be constructed from a FileOutputStream. For input, Serialization requires an ObjectInputStream, constructed from a FileInputStream.
Persistent Class requirements: JDO requires that the PersistenceCapable classes be either hand coded for persistence (not recommended) or that they be modified by a byte code post-processor. The post-processor adds several methods that allow management of the classes at runtime. Fields that are not suitable for persistence are automatically identified as not persistent (e.g. Thread, Socket). Serialization requires that the classes be declared to implement Serializable, and that each field that is *not* to be stored marked as "transient", even if it does not make sense (e.g. Thread, Socket). Special requirements for Serialization include a uniquing strategy (e.g. to guarantee that only one instance exist in the JVM) and a merging strategy (e.g. to join two serialized object graphs at runtime). These cases require special methods to be implemented in the PersistenceCapable class.
Store an object graph: Both Serialization and JDO will automatically store the closure of an object graph once one of the instances is identified as persistent. Both Serialization and JDO store the entire object graph as one file.
Retrieve an object graph: Serialization will retrieve an entire object graph with one call, with no option on how many objects to retrieve. JDO allows retrieval of a single object at a time.
Updates: Serialization does not support updates to serialized object graphs. If any change is made to the object graph, and then serialized, the new graph replaces the existing object graph in the file. JDO supports updates to object graphs. If any change is made to the object graph, only the changed objects are stored in the file.
Query: Serialization does not support queries. JDO allows a single instance or a collection of instances to be returned as the result of a query.
Lazy instantiation: Serialization will only retrieve an entire object graph. JDO allows instantiation of objects as required (as they are navigated from the instance first retrieved).
Transactions: Serialization and deserialization either succeed or fail. JDO supports transactions, in which changes applied to the data store in a transaction either succeed or fail, while other simultaneous transactions independently succeed or fail.
Remote server: Serialization does not support remote storage of data, except as transparently done via remote file servers (e.g. NFS). JDO supports remote storage, via the URL pattern. "fostore://host:port/path" refers to a remote JDO server on the specified host and port, using the relative path name specified.
Multi-user: Serialization is an atomic operation, in which all objects are serialized as a blob. Each user of the file gets their own copy of the objects, and each write of the file overwrites the existing contents. JDO supports multiple users of the same file, and allows non-conflicting updates of different parts of the object graph by different users. Conflicts are reported as exceptions.
Multiple Implementations: Serialization is built-in to every JVM. JDO is pluggable, allowing different JDO vendors to be used to store objects, at the user's choice. Some implementations simply store the objects in a file; others store objects in a relational database.
Performance: Performance has several aspects, as indicated in the discussion above. For storage of a small object graph, serialization will generally perform better, because there is simply less work to do, and less startup cost. But if there are large number of objects stored, the startup cost is amortized, and the differences are less. JDO visits each object only once while storing; Serialization performs a depth-first search of the object graph, so may visit the same object multiple times. JDO allows retrieval of only the objects needed by the application; Serialization will always retrieve the entire object graph at once.
For many applications, Serialization is a good strategy to use. It is relatively simple to understand and use, and performs well for single users with small object graphs. As the complexity and scale of the application increases, JDO's strengths become more significant.