Notice: This Wiki is now read only and edits are no longer possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.
EclipseLink/Development/JPA 2.0/persistence utils
JPA 2.0: PersistenceUtil
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