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/metamodel api
JPA 2.0: MetaModel API
Date | Committer(s) | Description |
---|---|---|
March 3, 2009 | gyorke | Initial feature template |
March 3, 2009 | mobrien | Start analysis |
Note: this document is in progress as of 20090304 for the next 3-5 weeks, therefore the content is in flux.
Summary
In JPA 2.0 the specification has defined standard APIs for representing the structure of a persistence unit model. This is referred to at the MetaModel APIs. There are two main aspects to providing this functionality. The first is the runtime model accessed from EntityManagerFactory.getMetaModel() and the second is the APT generated meta model classes. Our first goal is to provide functionality for runtime access.
For details see section 5.2 and 5.3 of Proposed Final Draft.
Work Estimate
- Investigate EclipseLink Metamodel
- approx 3 days
- Develop implementations of MetaModel or refactor current metamodel
- approx 10 days
- APT investigation and prototype
- approx 5 days
- APT tooling/testing
- approx 10 days
Analysis
Concepts
Metamodel?
- In the context of EclipseLink a metamodel is an abstract view of the managed classes in the persistence unit - we already have one of these that we construct in memory surrounding the class MetadataProcessor - we must transition or refactor this.
- We use the metamodel to construct a runtime query structure that is "object-based".
Relation to JPQL?
Functional Requirements
Requirements and constraints have traceability down to their associated use cases.
Requirements Table
Req# | A# | Use Cases# | Description |
---|---|---|---|
R1 | - | - | Support runtime Metamodel APIs |
R1.1 | - | - | Develop, leverage or refactor current Metamodel processor |
R1.2 | - | - | - |
R2 | A1 | - | Support APT generation of Canonical Metamodel classes see JPA 2.0 Spec. "Sect. 5.2.1" |
R2.1 | - | - | "For each managed class X in package p, a metamodel class X_ in package p is created."
Name collisions with entities that are already named Entity_ in the current package |
R2.2 | - | - | "The name of the metamodel class is derived from the name of the managed class by appending "_" to the name of the managed class." |
R2.3 | - | - | "The metamodel class X_ must be annotated with the javax.annotation.Generatedannotation and with the javax.persistence.TypesafeMetamodel annotation." |
R2.4 | - | - | "If class X extends another class S, where S is the most derived managed class (i.e., entity or mapped superclass) extended by X, then class X_ must extend class S_, where S_ is the metamodel class created for S." |
R2.5 | - | - | "For every persistent non-collection-valued attribute y declared by class X, where the type of y is Y, the metamodel class must contain a declaration as follows:"
public static volatile Attribute<X, Y> y; (and where javax.persistence.Attribute is imported by the class X_ ) |
R2.6 | - | - | For every persistent collection-valued attribute z declared by class X, where the element type of z is Z, the metamodel class must contain a declaration as follows: |
R2.6.1 | - | - | Collection if the collection type of z is java.util.Collection, then
public static volatile Collection<X, Z> z; (and where javax.persistence.Collection is imported by the class X_ ) |
R2.6.2 | - | - | Set if the collection type of z is java.util.Set, then
public static volatile Set<X, Z> z; (and where javax.persistence.Set is imported by the class X_ ) |
R2.6.3 | - | - | List if the collection type of z is java.util.List, then
public static volatile List<X, Z> z; (and where javax.persistence.List is imported by the class X_ ) |
R2.6.4 | - | - | Map if the collection type of z is java.util.Map, then
public static volatile Map<X, K, Z> z; where K is the type of the key of the map in class X (and and where javax.persistence.Map is imported by the class X_) |
R2.7 | - | - | Import statements must be included for all classes X, Y, Z, and K. specification down to the level of import statements vs fully qualified names - is a pending decision |
R2.8 | - | - | No extra runtime paramenters are required beyond existing -javaagent runtime flag |
Assumptions Table
A# | Req# | Use Cases# | Description |
---|---|---|---|
A1 | - | - | Java 5 is the minimum compile target we support (unchanged) |
A2 | - | - | Runtime environment for metamodel construction is SE and compilation time only |
Constraints Table
C# | A# | Use Cases# | Description |
---|---|---|---|
C1 | - | - | Dependency on the APT tool specific to the SUN JDK 1.5.0? Yes (tools.jar)
Determine if we are ok running on the IBM J9 JVM and WLS JRockit JVM in SE mode - Yes both have tools.jar. |
Metamodel Interface Class Structure
The criteria API runs on top of the metamodel API and expects that classes of the form X_ exist. It is the resposibility of the metamodel to create and compile these enhanced classes. We will start this investigation by using the ATP tool.
Running APT to create AnnotationProcessorFactory classes
APT Static Usage
- Start with the following APT tutorial by SUN that shows how to list class names
- Create an SE JPA project - remember to include the provider resource \jpa\org.eclipse.persistence.jpa\resource\META-INF\services\javax.persistence.spi.PersistenceProvider
- Add the EclipseLink classpath variable TOOLS_LIB = tools.jar so we can import com.sun.mirror
- Create an AnnotationProcessorFactory class
- Create a pointer to this class
- Create a UTF8 no extension text file com.sun.mirror.apt.AnnotationProcessorFactory with the content org.eclipse.persistence.apt.MetamodelAnnotationProcessorFactory
- Delete the 3 chars upside down ?.. before the same - so we do not get Illegal provider-class name: ?org
- Place this class into META-INF/services
- Compile and verify the following inner classes were created
- MetamodelAnnotationProcessorFactory$ListClassAp$ListClassVisitor.class
- MetamodelAnnotationProcessorFactory$ListClassAp.class
- Run APT in this project
APT Dynamic Usage
Design
API
Metamodel and Criteria packages interfaces API
The following static UML class diagram that illustrates the relationship between the Criteria and Metamodel API's will serve as a basis for the metamodel API part of this work.
Public API
Internal API
Annotation Processors
We require a design time annotation processing tool to create metamodel class files X_. The APT tool that has shipped since JDK 1.5 will be used to process and create our annotation factories.
APT
APT is the annotation processing tool that has been shipped since Java 5.
Design Criteria
Security
Concurrency
Performance
Configuration
Dependencies
- We have a compile time dependency on tools.jar for the com.sun.mirror packages.
Use Cases
Use cases have traceability back to their requirements and constraints via their id# and have a 1-1 correspondence with test cases.
Use Case ID# | Assumptions# | Requirements# | Description |
---|---|---|---|
UC1 | - | - | Construct object-based query definition object |
Concrete Use Cases
Details on each use case.
UC1:
- Preconditions
- Postconditions
- Path
- Exceptions
Variant Use Cases
Details on each variant (negative test) use case.
Implementation
Module Reuse
How much of the existing JPA annotation processor will be used or transitioned?
Modified Modules
EntityManagerImpl
package org.eclipse.persistence.internal.jpa; public class EntityManagerImpl implements org.eclipse.persistence.jpa.JpaEntityManager { // 266912: Criteria API and Metamodel API (See Ch 5 of the JPA 2.0 Specification) private javax.persistence.metamodel.Metamodel metaModel; public javax.persistence.metamodel.Metamodel getMetaModel() { return metaModel; }
New Modules
Testing
Example Code
Order Entity
package org.eclipse.persistence.example.jpa.server.business; import java.math.BigDecimal; import java.util.Set; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.ManyToOne; import javax.persistence.OneToMany; @Entity public class Order { @Id Integer orderId; @ManyToOne Customer customer; @OneToMany Set<Item> lineitems; Address shippingAddress; BigDecimal totalCost; }
Order_ TypesafeMetamodel
- The following class has been generated from the Order entity above
- Note the @Generated and @TypesafeMetamodel annotations
- Note the static volitile elements of type (Attribute, Set, Collection or List)
package org.eclipse.persistence.example.jpa.server.business; import java.math.BigDecimal; import javax.annotation.Generated; import javax.persistence.metamodel.Attribute; import javax.persistence.metamodel.Set; import javax.persistence.metamodel.TypesafeMetamodel; // added annotations from 5.2.1.3 @Generated(value="EclipseLink") @TypesafeMetamodel(Order.class) // from JPA 2.0 spec section 5 p.162 public class Order_ { public static volatile Attribute<Order, Integer> orderId; public static volatile Attribute<Order, Customer> customer; public static volatile Set<Order, Item> lineitems; public static volatile Attribute<Order, Address> shippingAddress; public static volatile Attribute<Order, BigDecimal> totalCost; }
Test Results
Open Issues
This section lists the open issues that are still pending that must be decided prior to fully implementing this project's requirements.
Issue # | Owner | Description / Notes |
---|---|---|
I1 20090304 | mobrien | compile time dependency on tools.jar for com.sun.mirror packages |
20090305 Meeting
- How to handle broken annotations? skip?
- How to handle dependent annotations that are broken
- performance (javac/apt) should be very fast
- dynamic regeneration on all modifications - should be automatic with -javaagent type ide hook
- For non-typesafe string based metadata accessors - if we verify type internally we have incremental type safety
- verify all examples in the spec work with get and not just the static metamodel
- Is there state for the metadata entity - 5.2.1.2 states it must be initialized
- Name collisions with entities that are already named Entity_ in the current package see 5.2.1.1
Decisions
This section lists decisions made. These are intended to document the resolution of open issues or constraints added to the project that are important.
Issue # | Description / Notes | Decision |
---|---|---|
Documentation
Wiki and formal documentation links here.
Future Considerations
During the research for this project the following items were identified as out of scope but are captured here as potential future enhancements. If agreed upon during the review process these should be logged in the bug system.