Table of Contents
The Naked Objects framework provides several extension points, one of which is the Object Store API used to persist domain objects. JPA Objects provides an implementation of this API to allow Naked Objects domain models to be persisted to an RDBMS. Note that the object store is also sometimes called the "persistor". For the purpose of this document the two are interchangeable[1].
In fact, JPA Objects also implements another Naked Objects API, namely the reflector. This is the component that is used to build up the metamodel. JPA Objects provides an extended version of the standard reflector, allowing selected JPA annotations to be identified as declarative business rules. This also allows JPA Objects to apply some validations on these annotations.
The project also provides a Maven archetype that includes a set of annotated classes and repository implementations for the example 'claims' application that ships with Naked Objects. A run through of using this archetype is given in Appendix A, Using the Maven Archetype.
The most notable aspect of using JPA
Objects is that we annotate our domain classes using the
JPA annotations
(javax.jpa.Entity
and so on). Because
JPA 1.0 does not capture enough semantics for our
purposes (eg there is no support for polymorphic "any" relationships),
we also use Hibernate's
annotations in some circumstances, exposing the fact that Hibernate is
the underlying JPA provider. We hope to remove this
dependency on Hibernate in a future release when we migrate to
JPA 2.0.
Implementations of repositories that are suitable for
prototyping (that is, as used by in-memory object store) are naive,
because they iterate over all instances. As such, they not suitable
for use by the JPA Objects; doing so would be
equivalent to performing a select * from some_table
-
with no where clause - and then filtering client-side in Java.
Therefore, using JPA Objects requires us to
provide implementations of repository interfaces. We use named queries
(@javax.jpa.NamedQuery
) to simplify this task.
Like Naked Objects itself, JPA Objects also provides an application library (or applib). And the intent is the same: to minimize the coupling from your domain objects to the framework.
In the current release of JPA Objects the only classes in the applib are adapters to allow Naked Objects value types to be persisted as user-defined types. This is discussed further in Chapter 6, Supporting Custom Value Types.
JPA Objects identifies the set of entities
that make up the domain model by walking the graph from the
repositories. These are registered as services in Naked Objects'
nakedobjects.properties
configuration
file.
If you have inheritance hierarchies then it may be necessary
to create dummy actions on your repositories so that all concrete
subclasses are registered. The subclasses can appear either as
parameters or as return types, and the action can be annotated as
@Hidden
so that it does not appear in the
user interface.
In addition, nakedobjects.properties
is
typically used to specify the persistor implementation, ie JPA
Objects' own persistor.
There are further details on configuring Naked Objects and JPA Objects in Chapter 7, Deploying JPA Objects.
[1] In fact, it is the persistor API that JPA Objects actually implements. Under client/server remoting there is an alternative persistor API that abstracts away the network.