ch.elca.el4j.services.persistence.hibernate.dao.extent
Class DataExtent

java.lang.Object
  extended by ch.elca.el4j.services.persistence.hibernate.dao.extent.DataExtent
All Implemented Interfaces:
Serializable

public class DataExtent
extends Object
implements Serializable

A DataExtent represents the extent of the graphs of objects to be loaded in a hibernate query.
Be careful in not mixing up the notion of an extent:
In this context it is referring to the extent of the DOM to be loaded from the underlying persistent store.
In other contexts like for example OpenJPA the notion can have a different meaning.

Principle:
An Extent represents a part of the DOM that should be loaded together.
It can be used to pool together associated entities in order to provide performance improvements over standard data fetching.
Specifying the extent when loading entities with Hibernate allows for tuning of lazy loading and eager fetching behavior.
For details about how to use the "Fetch Type" in order to control whether a field is fetched eagerly or lazily, see the corresponding reference manual of Java Persistence API (eg. http://java.sun.com/javaee/5/docs/api/javax/persistence/FetchType.html)
In a DataExtent we internally distinguish between fields, entities and collections:

Remark: When using DataExtent you don't have to have any knowledge about the db mapping or anything like that. It suffices to know the interface of the entity you are about to use. For example if you have:
 public class Employee {
        ...
        public Employee getManager() {...
 
To be sure that you can access the manager of an employee after retrieving it from the dao, add the manager to the extent you pass as an extra argument to the dao: dao.findById(id, extent.with("manager"));

Note that any part of the extent that is eagerly loaded according to the JPA metadata rules cannot be changed to a lazy loading behavior with DataExtent. On the other hand, all as lazy loading indicated parts can be forced to be loaded at runtime in each query.
Also, parts of the extent that does not get loaded but accessed at runtime will throw a LazyLoadingException as it would without using DataExtent's.

Features:
Remark: Be sure to import the static methods ExtentEntity.entity(java.lang.Class) and ExtentCollection.collection(java.lang.String, java.lang.Class) to create easily new Entities and Collections.

Sample code:
        // The Extent Object of type 'Person'
        extent = new DataExtent(Person.class);
        // Construct a complex graph:
        // Person has a List of Teeth, a Tooth has a 'Person' as owner, 
        // the owner has a list of 'Person' as friends, the friends are again
        // the same 'Person'-entity as defined in the beginning.
        extent.withSubentities(
                collection("teeth",
                        entity(Tooth.class)
                                .with("owner")
                        ),
                collection("friends", extent.getRootEntity())
        );
        
        // Extent of a File
        extent = new DataExtent(File.class);
        // Create a simple, light extent for an overview over the files
        extent.with("name", "lastModified", "fileSize", "mimeType");
        dao.getAll(extent);
        // Note: there will potentially be loaded more than you specify, if it is defined to be fetched eagerly

        // Another extent to see also the file content
        extent = new DataExtent(File.class);
        extent.with("name", "content", "lastModified", "fileSize", "mimeType");
        dao.findById(id, extent);

        // Extent in a reference DOM, where references are loaded lazily
        extent = new DataExtent(Publication.class);
        extent.all(3);
        dao.findByName(publicationName, extent);
        // Now you have loaded all referenced publications, books, papers, ... to a depth of 3
        // Eg. using the parent of the parent is now possible.
                        

Author:
Andreas Rueedlinger (ARR)
See Also:
for an example, Serialized Form
File-location:
DataExtent
Last check-in date:
2009-08-04 14:25:40 +0200 (Di, 04. Aug 2009) by swismer for revision 3874

Field Summary
static int DEFAULT_LOADING_DEPTH
          Defines the default loading depth.
 
Constructor Summary
DataExtent(Class<?> c)
          Default Creator.
 
Method Summary
 DataExtent all()
          Include all fields, entities and collections of the class.
 DataExtent all(int depth)
          Include all fields, entities and collections of the class.
 boolean equals(Object object)
          
 DataExtent freeze()
          Freeze the extent, meaning that no further changes to it are possible.
 String getExtentId()
          The id of the data extent.
 ExtentEntity getRootEntity()
          Root entity of the extent.
 int hashCode()
          
 DataExtent merge(DataExtent other)
          Merge two DataExtents.
 String toString()
          
 DataExtent with(String... fields)
          Extend the extent by the given fields.
 DataExtent without(String... fields)
          Exclude fields from the extent.
 DataExtent withSubentities(AbstractExtentPart... entities)
          Extend the extent by the given sub-entities.
 
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
 

Field Detail

DEFAULT_LOADING_DEPTH

public static final int DEFAULT_LOADING_DEPTH
Defines the default loading depth.

See Also:
Constant Field Values
Constructor Detail

DataExtent

public DataExtent(Class<?> c)
Default Creator.

Parameters:
c - the class of the root entity.
Method Detail

getRootEntity

public ExtentEntity getRootEntity()
Root entity of the extent.

Returns:
the root entity of the extent.

getExtentId

public String getExtentId()
The id of the data extent. If two extents contain the same subparts, this id should be equal.

Returns:
the id of the extent.

with

public DataExtent with(String... fields)
                throws NoSuchMethodException
Extend the extent by the given fields. Fields are either simple properties, sub-entities or collections.

Parameters:
fields - fields to be added.
Returns:
the new DataExtent Object.
Throws:
NoSuchMethodException

withSubentities

public DataExtent withSubentities(AbstractExtentPart... entities)
                           throws NoSuchMethodException
Extend the extent by the given sub-entities.

Parameters:
entities - entities to be added.
Returns:
the new DataExtent Object.
Throws:
NoSuchMethodException

without

public DataExtent without(String... fields)
Exclude fields from the extent. Fields are either simple properties, sub-entities or collections.

Parameters:
fields - fields to be excluded.
Returns:
the new DataExtent Object.

all

public DataExtent all()
Include all fields, entities and collections of the class. Exploration depth is DEFAULT_LOADING_DEPTH.

Returns:
the new DataExtent Object.

all

public DataExtent all(int depth)
Include all fields, entities and collections of the class.

Parameters:
depth - Exploration depth
Returns:
the new DataExtent Object.

merge

public DataExtent merge(DataExtent other)
Merge two DataExtents. Returns The class of the two rootEntities should be the same.

Parameters:
other - the extent to be merged with.
Returns:
the union of the extents.

freeze

public DataExtent freeze()
Freeze the extent, meaning that no further changes to it are possible.

Returns:
the frozen extent.

hashCode

public int hashCode()

Overrides:
hashCode in class Object

equals

public boolean equals(Object object)

Overrides:
equals in class Object

toString

public String toString()

Overrides:
toString in class Object


Copyright © 2005-2011 ELCA. All Rights Reserved.