8.4. Lazy Loading

Very few domain objects are standalone; most have properties and/or collections that reference other objects. This creates a problem for persistence technologies: if we load (or resolve) one object from the object store, how do we prevent having to load everything it refers to (and transitively, everything they refer to, and so on).

Lazy loading provides the solution to this, by returning proxies for the referenced objects. Only when these proxies are queried do they perform a further database query. In this way we "walk the graph" piecemeal.

Different JPA providers do this in different ways, and the proxy also varies depending on whether there is lazy loading of a property (referencing a single instance of some other object) or a collection (referencing many instances). JPA Objects uses Hibernate, which works as follows:

The programmer can influence lazy loading by specifying the fetch attribute of @javax.persistence.OneToOne and @javax.persistence.ManyToOne annotations:

The only other programming model restriction is that collections must provide a setter (even if only with private visibility) so that Hibernate can inject its own collection implementations.

Naked Objects itself also provides support for lazy loading, and is configured to support it out-of-the-box. This is needed in two main situations:

Naked Objects implementation also uses either CgLib or Javassist, though the implementation differs from Hibernate. In Section 2.5, “Specify a discriminator” we discussed the idea of an Oid - a unique identifier for every domain object. However, this Oid doesn't just float around, it is actually associated with a NakedObject. This is a wrapper (or adapter) for the underlying domain object. The Naked Objects framework maintains mappings so anyone can be looked up from the others:

Naked Objects' lazy loading support is managed through these NakedObject adapters. Each adapter keeps track of the "resolve state" of its corresponding pojo. An unresolved object has not yet been loaded, so any request to view its contents forces a load (across the network, for a client, or from the objectstore, for a server). A CgLib proxy is used to trigger the request to resolve the domain object if required; ultimately this is marshalled through the DomainObjectContainer#resolve() method.

How does all this tie into JPA Objects, though? Well, because Hibernate is used under the covers , we actually switch off Naked Objects' own lazy loading for deployments running server-side or as a webapp. Details of how to do is shown in Section 7.1, “Configure Naked Objects”.