Jump to: navigation, search

Difference between revisions of "EclipseLink/DesignDocs/371950"

Line 2: Line 2:
  
 
*[http://bugs.eclipse.org/371950 Enhancement Request 371950]
 
*[http://bugs.eclipse.org/371950 Enhancement Request 371950]
 
+
== Purpose ==
== Purpose ==
+
  
 
This feature is to look at caching the metadata project so that the setup can avoid costs associated with reading in multiple orm.xml and annotation processing on entities within a persistence unit to rebuild it unnecessarily.  
 
This feature is to look at caching the metadata project so that the setup can avoid costs associated with reading in multiple orm.xml and annotation processing on entities within a persistence unit to rebuild it unnecessarily.  
  
== Requirements ==
+
== Requirements ==
  
#EntityManagerFactory and EntityManager instance creation use properties that allow overriding metadata settings/properties the same as it would if project caching was not used  
+
# EntityManagerFactory and EntityManager instance creation use properties that allow overriding metadata settings/properties the same as it would if project caching was not used
#Project caching must allow weaving to happen
+
# Project caching must allow weaving to occur
#It must be configurable to allow alternate implementations to cache the project differently  
+
# It must be configurable to allow alternate implementations to cache the project differently
#The project will be read from/writen to the cache prior to login, prior to converting String ClassNames into Classes.
+
# The project will be read from/writen to the cache prior to login, prior to converting String ClassNames into Classes.
 +
# It not break any current functionality such as remote sessions.
  
== Design ==
+
== Design ==
  
=== PersistenceUnitProperties  ===
 
  
public static final String PROJECT_CACHE_ACCESSOR = "eclipselink.project-cache-accessor"; will be the base property to configure this feature, and will take a string value representing shipped implementations or the a <package.class> name of a subclass implementation of the ProjectCache interface. By default a project cache accessor will not be used.
+
=== PersistenceUnitProperties ===
  
The "eclipselink.project-cache-accessor.<implementationShortName>" subset of properties will be used for implementation specific properties.  
+
public static final String PROJECT_CACHE_ACCESSOR = "eclipselink.project-cache-accessor";
 +
will be the base property to configure this feature, and will take a string value representing shipped implementations or the a <package.class> name of a subclass implementation of the ProjectCache interface
  
=== Interface ===
+
The "eclipselink.project-cache-accessor.<implementationShortName>" subset of properties will be used for implementation specific properties.
 +
=== Interface ===
  
 
<source lang="java">
 
<source lang="java">
Line 31: Line 32:
 
</source>
 
</source>
  
=== Included Implementation  ===
 
  
This feature will include a ProjectCacheAccessor implementation that uses java serialization to read to/write from a file which can be used by specifying the PROJECT_CACHE_ACCESSOR property with a value of "java-serialization" This implementation will also require the file location be specified, and will rely on a "eclipselink.project-cache-accessor.java-serialization.file" property being defined.
+
=== Included Implementation - Java Serialization ===
 +
 
 +
This feature will include a ProjectCacheAccessor implementation that uses java serialization to read to/write from a file which can be used by specifying the PROJECT_CACHE_ACCESSOR property with a value of "java-serialization".
 +
This implementation will also require the file location be specified, and will rely on a "eclipselink.project-cache-accessor.java-serialization.file" property being defined
 +
 
 +
==== Changes required for Java Serialization ====
 +
Many settings built from the metadata are stored in the session and would be lost when serializing the project without changes to store them or reprocessing the metatadata
 +
# JPAQueries.  These will need to be stored in the project instead of the session.  In addition to only JPQL queries being stored as JPAQueries, all named queries will need to be put into this collection and have processing delayed.  The JPAQuery class will be changed to handle native SQL, stored function and PLSQL query processing.
 +
# A collection of Strings representing names of classes to be weaved will need to be stored within the project.  Metadata is used to gather the classes that are needed for weaving, but not all classes required to be weaved will have descriptor representations.  Without this, weaving could not occur without reprocessing the metadata.
 +
# The org.eclipse.persistence.sessions.Project references many classes that will need to be made serializable. 
 +
# org.eclipse.persistence.sessions.Project and referenced classes have many variables set through metadata configuration that are transient and will need to be serialized.
 +
## many remaining transients set through the constructors will need to be lazy initialized in accessors  or null checks added where they are used.
 +
# ClassDescriptor will store a list of DescriptorCustomizers string names.  These will be processed after serialization instead of immediately as user methods could add class dependencies that would interfer with weaving.
 +
# DescriptorEventManager will store a list of lists.  Each inner list will contain the raw data needed to build a single DescriptorEventListener that would have been set by metadata processing.  This will be used in EntityManagerSetupImpl when processing the deserialized projects to create the appropriate EventListener instances.
 +
## User classes and methods stored within JPA EntityListeners are not serializable and cannot be handled directly within DescriptorEventManager without adding jpa dependencies.
 +
#  DatasourceCall will define a readObject method when deserializing.  This method will correct parameterTypes collection so that the current static Integer values are used.  Default deserialization causes new instances to be used breaking == equality used internally. 
 +
# org.eclipse.persistence.queries.ConstructorResult will maintain a String targetClassName in addition to the transient targetClass.  The targetClass will then get set during the convertClassNamesToClasses process
 +
 
 +
=== Open Issues ===
 +
# StructureConverters will also need to be stored in the project, and then moved to the platform instance in the tail end of deploy. 
 +
## This was missed because there were no test failures indicating a problem.  A string storing the StructConverter implementation class name might be enough but needs looking into. 
 +
# This feature runs into the same multitenant issues as Metadatasource, such as requiring a different project for different tenants or when weaving.
 +
# The contract for building DescriptorEventListeners needs to be laid out in the ProjectCacheAccessor.  It might be better to use a class instead of a list of values where order might be important.

Revision as of 15:59, 24 May 2012

EclipseLink Metadata Cache

Purpose

This feature is to look at caching the metadata project so that the setup can avoid costs associated with reading in multiple orm.xml and annotation processing on entities within a persistence unit to rebuild it unnecessarily.

Requirements

  1. EntityManagerFactory and EntityManager instance creation use properties that allow overriding metadata settings/properties the same as it would if project caching was not used
  2. Project caching must allow weaving to occur
  3. It must be configurable to allow alternate implementations to cache the project differently
  4. The project will be read from/writen to the cache prior to login, prior to converting String ClassNames into Classes.
  5. It not break any current functionality such as remote sessions.

Design

PersistenceUnitProperties

public static final String PROJECT_CACHE_ACCESSOR = "eclipselink.project-cache-accessor"; will be the base property to configure this feature, and will take a string value representing shipped implementations or the a <package.class> name of a subclass implementation of the ProjectCache interface

The "eclipselink.project-cache-accessor.<implementationShortName>" subset of properties will be used for implementation specific properties.

Interface

public interface ProjectCacheAccessor {
  public Project retrieveProject(Properties properties, Classloader loader);
  public void storeProject(Project project, Properties properties);
}


Included Implementation - Java Serialization

This feature will include a ProjectCacheAccessor implementation that uses java serialization to read to/write from a file which can be used by specifying the PROJECT_CACHE_ACCESSOR property with a value of "java-serialization". This implementation will also require the file location be specified, and will rely on a "eclipselink.project-cache-accessor.java-serialization.file" property being defined.

Changes required for Java Serialization

Many settings built from the metadata are stored in the session and would be lost when serializing the project without changes to store them or reprocessing the metatadata

  1. JPAQueries. These will need to be stored in the project instead of the session. In addition to only JPQL queries being stored as JPAQueries, all named queries will need to be put into this collection and have processing delayed. The JPAQuery class will be changed to handle native SQL, stored function and PLSQL query processing.
  2. A collection of Strings representing names of classes to be weaved will need to be stored within the project. Metadata is used to gather the classes that are needed for weaving, but not all classes required to be weaved will have descriptor representations. Without this, weaving could not occur without reprocessing the metadata.
  3. The org.eclipse.persistence.sessions.Project references many classes that will need to be made serializable.
  4. org.eclipse.persistence.sessions.Project and referenced classes have many variables set through metadata configuration that are transient and will need to be serialized.
    1. many remaining transients set through the constructors will need to be lazy initialized in accessors or null checks added where they are used.
  5. ClassDescriptor will store a list of DescriptorCustomizers string names. These will be processed after serialization instead of immediately as user methods could add class dependencies that would interfer with weaving.
  6. DescriptorEventManager will store a list of lists. Each inner list will contain the raw data needed to build a single DescriptorEventListener that would have been set by metadata processing. This will be used in EntityManagerSetupImpl when processing the deserialized projects to create the appropriate EventListener instances.
    1. User classes and methods stored within JPA EntityListeners are not serializable and cannot be handled directly within DescriptorEventManager without adding jpa dependencies.
  7. DatasourceCall will define a readObject method when deserializing. This method will correct parameterTypes collection so that the current static Integer values are used. Default deserialization causes new instances to be used breaking == equality used internally.
  8. org.eclipse.persistence.queries.ConstructorResult will maintain a String targetClassName in addition to the transient targetClass. The targetClass will then get set during the convertClassNamesToClasses process

Open Issues

  1. StructureConverters will also need to be stored in the project, and then moved to the platform instance in the tail end of deploy.
    1. This was missed because there were no test failures indicating a problem. A string storing the StructConverter implementation class name might be enough but needs looking into.
  2. This feature runs into the same multitenant issues as Metadatasource, such as requiring a different project for different tenants or when weaving.
  3. The contract for building DescriptorEventListeners needs to be laid out in the ProjectCacheAccessor. It might be better to use a class instead of a list of values where order might be important.