Jump to: navigation, search

EclipseLink/Development/JPA 2.0/persistence utils

< EclipseLink‎ | Development‎ | JPA 2.0
Revision as of 14:54, 22 September 2009 by Gordon.yorke.oracle.com (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

JPA 2.0: PersistenceUtil

JPA 2.0 Root | bug 281884

Date Committer(s) Description
June 29, 2009 gyorke Initial feature template
September 22, 2009 tware Initial Design notes

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.

  • isLoaded(entity, attribute) - return true if the static method returns true, false if it returns false or null
  • isLoaded(entity) - return true if the static method returns true, false if it returns false or null
  • getIdentifier(entity)

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

Testing

The following tests will be added

PersistenceUnitUtil

  • isLoaded(entity) - ensure a loaded entity returns true
  • isLoaded(entity, attribute) - ensure a loaded xToOne returns true
  • isLoaded(entity, attribute) - ensure a non-loaded xToOne returns false
  • isLoaded(entity, attribute) - ensure a loaded xToMany returns true
  • isLoaded(entity, attribute) - ensure a non-loaded xToMany returns false
  • getIdentifier(entity) simple PK
  • getIdentifier(entity) - - composite PK

ProviderUtil

  • isLoadedWithReference(entity, attribute) - ensure a loaded xToOne returns true
  • isLoadedWithReference(entity, attribute) - ensure a non-loaded xToOne returns false
  • isLoadedWithReference(entity, attribute) - ensure a loaded xToMany returns true
  • isLoadedWithReference(entity, attribute) - ensure a non-loaded xToMany returns false
  • isLoadedWithWithoutReference(entity, attribute) - ensure a loaded xToOne returns true
  • isLoadedWithWithoutReference(entity, attribute) - ensure a non-loaded xToOne returns false
  • isLoadedWithWithoutReference(entity, attribute) - ensure a loaded xToMany returns true
  • isLoadedWithWithoutReference(entity, attribute) - ensure a non-loaded xToMany returns false
  • isLoadedWithWithoutReference(entity, attribute) - ensure a non managed class returns unknown and the getter method is not called
  • isLoaded(entity) - ensure an entity with no fetch group loaded by find returns true
  • isLoaded(entity) - ensure the result of getReference returns false
  • isLoaded(entity) - ensure a non managed class returns unknown and the getter method is not called

Open Issues