JPA 2.0: PersistenceUtil

Summary

The JPA 2.0 specification provides two ways of inquiring about the load-state of classes. PersistenceUnitUtil provides a way of querying a single EntityManagerFactory and ProviderUtil provides a way of querying a whole persistence provider. These interfaces to provide a validation mechanism where a requester can inquire about the state of indirection.

Work Estimate

PersistenceUnitUtil - 2 days

ProviderUtil - 3 days

Functional Requirements

The functional requirements are defined by the specification.

PersistenceUnitUtil has the following methods:

isLoaded(entity) - return whether all the eager fields of an entity are loaded

isLoaded(entity, attribute) - returh whether the named attribute is loaded on the given entity

getIdentifier - get the primary key of the object

ProviderUtil has the following methods

isLoadedWithReference(entity, attribute) - return whether the entity has all its eager fields loaded and the given attribute is loaded

isLoadedWithoutReference(entity, attribute) - return whether the entity has all its eager fields loaded and the given attribute is loaded. Unless known to be woven by us attribute must not be accessed to prevent triggering another provider's indirection

isLoaded(entity) - return whether the entity has all its eager fields loaded. Unless known to be woven by us attribute must not be accessed to prevent triggering another provider's indirection

Existing Feature Impact

Feature

Supported

Notes

Design

PersistenceUnitUtil

The PersistenceUnitUtil interface will be implemented by our EntityManagerFactoryImpl class.

The logic required by the interface-defined methods will, for the most part, be defined in static methods. This will allow the logic to be shared by the ProviderUtil implementations. The following static methods will be added:

isLoaded(entity, attribute, session) - return null if there is no descriptor for entity, or no mapping for attribute, else delegate to isLoaded(entity, attribute, Mapping)

isLoaded(entity, attribute, mapping) - if mapping is a LAZY ForeignRefernceMapping, use the indirection policy to determine if it is instantiated, else check the fetch group to see if it is fetched

isLoaded(entity, session) - return null if there is no descriptor for entity, iterate through the mappings of the entity an call isLoaded(entity, attribute, mapping) on each and return false if any are not loaded

getIdentifier(entity) - throw an IllegalArgumentException if there is no descriptor for the entity, or if the descriptor does not have CMPPolicy. Use the CMPPolicy to build an instance of the primaryKey and return it

The following non static methods will be added (to satisfy the interface). All will call the appropriate static method listed above and supply the session for this factory.

ProviderUtil

ProviderUtil adds three methods, two of which have the following restriction:

"The provider's implementation of this method must not obtain a reference to an attribute value, as this could trigger the loading of entity state if the entity has been provided by a different provider."

Our implementation of these methods will interpret the above as follows:

We will return UNKNOWN for any entity that we have not weaved (does not implement our PersistenceWeaved interface)

If an entity implements PersistenceWeaved, we will consider it safe to look at the attributes because we will know that we are the provider, that weaving has occured, and as a result, the type of the attribute will be IndirectList or ValueHolder. We will ensure we do not trigger the IndirectList or ValueHolder when we look at it

The following methods will be implemented

isLoadedWithReference - iterate through all the entity manager setup impls and for the ones that are deployed, call the static isloaded method for both the full entity and for the specific attribute

isLoadedWithoutRefernce - check that the entity is an instance of PersistenceWeaved and if so, call isLoadedWithReference

isLoaded - check that the entity is an instance of PersistenceWeaved and if so, call isLoadedWithReference

Documentation

The only documentation for this feature will be the javadoc for the implemented methods