![]() | ![]() |
![]() |
| Project | Ver 1.1 | Ver 1.2 | JDO | JPA | Guides | Tools |
| 1.2 | Persistence | JDO ORM | JPA ORM | Runtime | JDO Runtime | JPA Runtime | Extensions | Developer |
The comparison of JDO and JPA shows the principal differences between the two main Java persistence APIs. This page goes further and lists some other operational differences.
JDO 2 has richer and well defined instance lifecycles. JDO 2.0 denies access to fields of persistent objects after being deleted, while JPA 1.0 allows it. JPA 1.0 does not specify the behavior of accessing non loaded fields for a deleted object.
JPA mandates the types byte[], java.lang.Byte[], char[] and java.lang.Character[] to be serialized to one column. JDO 2 is more flexible allow the persistence of these types to its own table, or serializing to a column.
JPA does not allow fields marked as transient to be persisted. JDO allows it by declaring the field as persistent in the metadata.
It's unclear whether JPA persists these fields. JDO does not allow persistence of these fields.
JDO 2 has much more strategies. For example, the UUID-HEX and UUID-String are strategies only available in JDO. Both specifications have SEQUENCE strategies, however some databases do not have native sequence support. For JDO, if SEQUENCE strategy is used and the database does not support sequences, the JDO implementation can create a SEQUENCE TABLE (this is not specified in JDO), while in JPA the solution is to use the strategy called GeneratorType.TABLE. JPA GeneratorType.AUTO is equivalent to the JDO NATIVE strategy. JDO allows the definition of custom strategies by implementing the Sequence interface. JPA does not allow custom strategies.
To attain higher portability levels in the database schema between implementations it's desired that a specification defines defaults when the ORM generates the database schema. JDO 2 defines defaults for mapping types to jdbc types like int to INTEGER, String to VARCHAR and so on. JPA does not define any default.
While JPA only supports persistent classes as value of Maps, JDO 2 allows persistent classes to be used as key, value or both. JPA allows only simple types as keys of Maps. Another disadvantage of JPA is that the key of the Map must be mapped to a field, and if not mapped, it will default to the primary key of the value type. JDO 2 allows the usage of surrogate columns (not assigned to any field) or any field in value persistent class.
While JPA only supports persistent classes as elements of Collections, JDO 2 allows any element type.
Since JPA only supports persistent classes as elements, it has an OrderBy annotation where you can say which field is used to order the collection. On the other hand, JDO 2 allows the usage of surrogate columns (not assigned to any field) or any field in persistent classes. In JPA, the order of elements is not maintained. The @OrderBy is used during load of list elements and after that the List in memory does not have ordering managed by the implementation.
This section maps JDO to JPA operators.
JPQL keywords are not case sensitive. JDOQL keywords are only lower cased or upper cased.
JDO allows to restrict queries to return subclasses for candidate classes (EXCLUDE SUBCLASSES). JPA (JPA §3.§.5) always returns the candidate class and sub classes.
JPA defines the format default identifiers are generated when not provided by user. JDO does not define a standard.
JPA and JDO have callbacks invoked on persistent objects, and they both have callbacks invoked on listener objects. JDO defines the interfaces: ClearCallback, AttachCallback, DeleteCallback, DetachCallback, LoadCallback and StoreCallback - these interfaces must be implemented by persistent class in order to have callbacks invoked on persistent objects. In JPA, there is no interface to be implemented, and callbacks are invoked on methods annotated with the PrePersist, PostPersist, PreRemove, PostRemove, PreUpdate, PostUpdate or PostLoad annotations. In JPA any method is valid to be annotated for callback. For lifecycle listeners, JDO defines the interfaces: AttachLifecycleListener, ClearLifecycleListener, CreateLifecycleListener, DeleteLifecycleListener, DetachLifecycleListener, DirtyLifecycleListener, LoadLifecycleListener and StoreLifecycleListener. In JPA, the lifecycle methods must be annotated with PrePersist, PostPersist, PreRemove, PostRemove, PreUpdate, PostUpdate or PostLoad annotations, and there is no need to implement an interface. In JPA, lifecycle listeners must be declared with annotations or metadata files. In JDO, lifecycle listener cannot be declared and must be registered at runtime through the PersistenceManager or PersistenceManagerFactory interfaces. JPA has no interfaces to register lifecycle listeners at runtime. JPA has lifecycle listeners that applies to all persistent classes in the persistent unit. These are called default lifecycle listeners which can be declared only in the metadata file. Officially, lifecycle listeners is known as entity listeners in JPA. Lifecycle listeners is a JDO term. In JPA, if lifecycle callbacks raise RuntimeException the transaction is rolled back. (or marked to be rolled back? To verify)
JPA has the concept of entity names which are unique logical names for the persistent classes. Entity names are used as alias for class names (JPA §4.3.1). JDO has no concept similar to it. JPA Query: Select p From Product p SELECT this FROM package.Product
In JPA if some expections are thrown from inside the implementation transactions are marked to rollback. JDO does not mark transactions to rollback in case of exceptions.
JPA Embeddable classes cannot have identity §2.1.5. In JDO the concept is called embedded-only, and since JDO is silent about it, it should be supported.
JDO2 allows
JPA1 allows
JPOX 1.2 provides MetaData extensions for JDO2 so that you have the same full control over these operations.
This section maps JDO to JPA annotations.
|