JPOX
JPOX
 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
JPOX 1.2
Plugins
Overview

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.



Matrix
FeatureJDO 2.0JPA 1.0JPOXPlug-in
Mature Specification/Product
Type : Java5 EnumsJava5
Datastore IdentityCore
Test coverage (TCK, unit tests)1277 tests465 tests1300+ tests


Lifecycle

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.



Mapping Limitations

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.



Transient Fields

JPA does not allow fields marked as transient to be persisted. JDO allows it by declaring the field as persistent in the metadata.



Static and Final Fields

It's unclear whether JPA persists these fields. JDO does not allow persistence of these fields.



Default column size

JPA defaults to 255. JDO defaults to 256.



Identity Strategy / Generator Type

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.



Default mapping of java types to jdbc types

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.



java.util.Map

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.



java.util.Collection

While JPA only supports persistent classes as elements of Collections, JDO 2 allows any element type.



java.util.List

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.



Query operators

This section maps JDO to JPA operators.

JPQLJDOQL
expr = expr2expr == expr2
expr <> expr2expr != expr2
expr IS NULLexpr == null
expr IS NOT NULLexpr != null
expr.IS EMPTYexpr.isEmpty()
expr IS NOT EMPTY!expr.isEmpty()



Query keywords

JPQL keywords are not case sensitive. JDOQL keywords are only lower cased or upper cased.



Query subclasses

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.



Default identifiers for column and table names

JPA defines the format default identifiers are generated when not provided by user. JDO does not define a standard.



Callback listeners

JPAJDONotes
--postCreateJDO postCreate is invoked only on lifecycle listeners
prePersistpreStore
postPersistpostStoreJDO postStore is invoked only on lifecycle listeners
postLoadpostLoadOn refresh JPA invokes postLoad callbacks even it was invoked before; JDO invokes postLoad only at the first time the instance is loaded.
preRemovepreDelete
postRemovepostDeleteJDO postDelete is invoked only on lifecycle listeners
preUpdatepreStore
postUpdatepostStoreJDO postStore is invoked only on lifecycle listeners
--preDirtycalled before the object is changed, JDO preDirty is invoked only on lifecycle listeners
--postDirtycalled after the object is changed; JDO postDirty is invoked only on lifecycle listeners
--preAttach
--postAttach
--preDetach
--postDetach
--preClearcalled before clearing object fields (e.g. during commit)
--postClearcalled after clearing object fields (e.g. during commit); JDO postClear is invoked only on lifecycle listeners

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)



Entity Names

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
JDO Query:
SELECT this FROM package.Product



Mark for rollback

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.



Embeddable classes

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.



Enum

Enums are persistent by default in JPA, while in JDO 2.0 they are not supported.



Cascade of operations

JDO2 allows

  • Persistence of reachable objects at persist and update, but you cant turn this off
  • Deletion of reachable objects at delete, and you can turn this on/off (default = off)
  • No refresh of reachable objects when you refresh an object.

JPA1 allows

  • Persistence of reachable objects at persist and update, and you can turn this on/off (default = off)
  • Deletion of reachable objects at delete, and you can turn this on/off (default = off)
  • Refresh of reachable objects when you refresh an object, and you turn this on/off (default = off)

JPOX 1.2 provides MetaData extensions for JDO2 so that you have the same full control over these operations.



Annotations

This section maps JDO to JPA annotations.

JPAJDO
MapKey#namekey#mapped-by
--key#column
--value#mapped-by
--value#column
OrderByorder#mapped-by
--order#column
ExcludeSuperClassListeners--
EntityListeners--
PrePersist--
PostPersist--
PreRemove--
PostRemove--
PreUpdate--
PostUpdate--
PostLoad--
Enumerated--
JoinTablejoin
JoinTable#joinColumnsjoin/column
JoinTable#inverseJoinColumnselement/column