HHH-4202 - Implement JPA 2.0 metamodel APIs

git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@17850 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Steve Ebersole 2009-10-27 18:49:25 +00:00
parent 2176af1144
commit e229d0171a
3 changed files with 171 additions and 126 deletions

View File

@ -1,32 +1,37 @@
<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-parent</artifactId>
<version>3.5.0-SNAPSHOT</version>
<relativePath>../parent/pom.xml</relativePath>
</parent>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<packaging>jar</packaging>
<name>Hibernate Entitity Manager</name>
<description>Hibernate Entitity Manager</description>
<!-- Annotations and Commons-Annotations both use the ANN JIRA key -->
<issueManagement>
<system>jira</system>
<url>http://opensource.atlassian.com/projects/hibernate/browse/ANN</url>
</issueManagement>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<groupId>${project.groupId}</groupId>
<artifactId>hibernate-core</artifactId>
<version>${version}</version>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<groupId>${project.groupId}</groupId>
<artifactId>hibernate-annotations</artifactId>
<version>${version}</version>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
@ -41,26 +46,41 @@
<artifactId>jpa-api</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<!--
Only really needed for the antrun plugin defined below (which in turn is only really needed
to work around a missing feature on the compile plugin; lovely no?). However I have not
found a way to declare this dependency local to the antrun plugin and then reference it
from the <javac/>'s <classpath/> :(
-->
<groupId>${project.groupId}</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<version>1.0.0-Alpha1-SNAPSHOT</version>
<version>1.0.0-SNAPSHOT</version>
<scope>test</scope>
<exclusions>
<exclusion>
<!-- Use the jpa-api defined here, crossing fingers they match up signature-wise -->
<groupId>org.hibernate.java-persistence</groupId>
<artifactId>jpa-api</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<groupId>${project.groupId}</groupId>
<artifactId>hibernate-core</artifactId>
<version>${version}</version>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<groupId>${project.groupId}</groupId>
<artifactId>hibernate-annotations</artifactId>
<version>${version}</version>
<version>${project.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<testResources>
<testResource>
@ -70,7 +90,7 @@
<testResource>
<filtering>true</filtering>
<directory>src/test/bundles</directory>
<targetPath>../bundles</targetPath>
<targetPath>../bundles</targetPath>
</testResource>
</testResources>
<plugins>
@ -84,65 +104,21 @@
<configuration>
<tasks>
<echo>processing JPA annotations</echo>
<property name="target.dir" value="target/generated-jpamodel-classes"/>
<property name="target.dir" value="${project.build.directory}/generated-src/jpamodelgen"/>
<mkdir dir="${target.dir}"/>
<javac srcdir="src/test/java" destdir="${target.dir}" failonerror="false" excludes="test/**" fork="true" executable="${jdk16_home}/bin/javac" target="1.5">
<javac srcdir="${project.build.testSourceDirectory}"
destdir="${target.dir}"
failonerror="false"
fork="true"
executable="${jdk16_home}/bin/javac"
target="1.5">
<compilerarg value="-proc:only"/>
<classpath>
<path refid="maven.test.classpath"/>
</classpath>
</javac>
</tasks>
<sourceRoot>generate</sourceRoot>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<version>1.7.0</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.3</version>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-test-source</goal>
</goals>
<configuration>
<sources>
<source>target/generated-jpamodel-classes</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>package-tests</id>
<phase>process-test-classes</phase>
<configuration>
<tasks>
<property name="package.dir" value="${basedir}/target/test-packages"/>
<property name="package.tmp.dir" value="${basedir}/target/tmp"/>
<property name="classes.dir" value="${project.build.directory}/test-classes"/>
<property name="testresources.dir" value="${basedir}/target/bundles"/>
<ant antfile="${basedir}/build.xml">
<target name="package"/>
</ant>
</tasks>
<testSourceRoot>${project.build.directory}/generated-src/jpamodelgen</testSourceRoot>
</configuration>
<goals>
<goal>run</goal>
@ -150,6 +126,29 @@
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>package-tests</id>
<phase>process-test-classes</phase>
<configuration>
<tasks>
<property name="package.dir" value="${basedir}/target/test-packages" />
<property name="package.tmp.dir" value="${basedir}/target/tmp" />
<property name="classes.dir" value="${project.build.directory}/test-classes" />
<property name="testresources.dir" value="${basedir}/target/bundles" />
<ant antfile="${basedir}/build.xml">
<target name="package" />
</ant>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
@ -170,79 +169,77 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<forkMode>pertest</forkMode>
<additionalClasspathElements>
<additionalClasspathElement>${basedir}/target/test-packages/cfgxmlpar.par</additionalClasspathElement>
<additionalClasspathElement>${basedir}/target/test-packages/defaultpar.par</additionalClasspathElement>
<additionalClasspathElement>${basedir}/target/test-packages/excludehbmpar.par</additionalClasspathElement>
<additionalClasspathElement>${basedir}/target/test-packages/explicitpar.par</additionalClasspathElement>
<additionalClasspathElement>${basedir}/target/test-packages/explodedpar.par</additionalClasspathElement>
<additionalClasspathElement>${basedir}/target/test-packages/externaljar.jar</additionalClasspathElement>
<additionalClasspathElement>${basedir}/target/test-packages/nesteddir.ear</additionalClasspathElement>
<additionalClasspathElement>${basedir}/target/test-packages/nestedjar.ear</additionalClasspathElement>
<additionalClasspathElement>${basedir}/target/test-packages/overridenpar.jar</additionalClasspathElement>
<additionalClasspathElement>${basedir}/target/test-packages/space par.par</additionalClasspathElement>
<additionalClasspathElement>${basedir}/target/test-packages/war.war</additionalClasspathElement>
</additionalClasspathElements>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<forkMode>pertest</forkMode>
<additionalClasspathElements>
<additionalClasspathElement>${basedir}/target/test-packages/cfgxmlpar.par</additionalClasspathElement>
<additionalClasspathElement>${basedir}/target/test-packages/defaultpar.par</additionalClasspathElement>
<additionalClasspathElement>${basedir}/target/test-packages/excludehbmpar.par</additionalClasspathElement>
<additionalClasspathElement>${basedir}/target/test-packages/explicitpar.par</additionalClasspathElement>
<additionalClasspathElement>${basedir}/target/test-packages/explodedpar.par</additionalClasspathElement>
<additionalClasspathElement>${basedir}/target/test-packages/externaljar.jar</additionalClasspathElement>
<additionalClasspathElement>${basedir}/target/test-packages/nesteddir.ear</additionalClasspathElement>
<additionalClasspathElement>${basedir}/target/test-packages/nestedjar.ear</additionalClasspathElement>
<additionalClasspathElement>${basedir}/target/test-packages/overridenpar.jar</additionalClasspathElement>
<additionalClasspathElement>${basedir}/target/test-packages/space par.par</additionalClasspathElement>
<additionalClasspathElement>${basedir}/target/test-packages/war.war</additionalClasspathElement>
</additionalClasspathElements>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<profile>
<id>doc</id>
<build>
<plugins>
<plugin>
<groupId>org.jboss.maven.plugins</groupId>
<artifactId>maven-jdocbook-plugin</artifactId>
<version>2.2.0</version>
<version>2.1.0</version>
<extensions>true</extensions>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jdocbook-style</artifactId>
<version>2.0.0</version>
<version>1.0.2</version>
<type>jdocbook-style</type>
</dependency>
</dependencies>
<configuration>
<sourceDocumentName>master.xml</sourceDocumentName>
<sourceDirectory>${basedir}/src/main/docbook</sourceDirectory>
<masterTranslation>en</masterTranslation>
<sourceDirectory>${basedir}/src/main/docbook/en</sourceDirectory>
<masterTranslation>en-US</masterTranslation>
<imageResource>
<directory>${basedir}/src/main/docbook/en/images</directory>
</imageResource>
<formats>
<format>
<formatName>pdf</formatName>
<stylesheetResource>classpath:/xslt/org/hibernate/jdocbook/xslt/pdf.xsl</stylesheetResource>
<finalName>hibernate_reference.pdf</finalName>
<stylesheetResource>classpath:/xslt/hibernate/pdf/main-pdf.xsl</stylesheetResource>
<finalName>hibernate-validator-legacy-guide.pdf</finalName>
</format>
<format>
<formatName>html_single</formatName>
<stylesheetResource>classpath:/xslt/org/hibernate/jdocbook/xslt/xhtml-single.xsl
</stylesheetResource>
<stylesheetResource>classpath:/xslt/hibernate/html/main-single.xsl
</stylesheetResource>
<finalName>index.html</finalName>
</format>
<format>
<formatName>html</formatName>
<stylesheetResource>classpath:/xslt/org/hibernate/jdocbook/xslt/xhtml.xsl
</stylesheetResource>
<stylesheetResource>classpath:/xslt/hibernate/html/main-chunk.xsl
</stylesheetResource>
<finalName>index.html</finalName>
</format>
</formats>
<options>
<xincludeSupported>true</xincludeSupported>
<xmlTransformerType>saxon</xmlTransformerType>
<!-- needed for uri-resolvers; can be ommitted if using 'current' uri scheme -->
<!-- could also locate the docbook dependency and inspect its version... -->
<docbookVersion>1.72.0</docbookVersion>
<localeSeparator>-</localeSeparator>
<useRelativeImageUris>true</useRelativeImageUris>
</options>
</configuration>
<executions>
@ -259,5 +256,6 @@
</plugins>
</build>
</profile>
</profiles>
</profiles>
</project>

View File

@ -30,6 +30,7 @@ import java.util.Map;
import java.util.Set;
import javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.SingularAttribute;
import javax.persistence.MappedSuperclass;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
@ -40,6 +41,10 @@ import org.hibernate.engine.SessionFactoryImplementor;
* <p/>
* This contextual information includes data needing to be processed in a second pass as well as
* cross-references into the built metamodel classes.
* <p/>
* At the end of the day, clients are interested in the {@link #getEntityTypeMap} and {@link #getEmbeddableTypeMap}
* results, which represent all the registered {@link #registerEntityType entities} and
* {@link #registerEmbeddedableType embeddabled} respectively.
*
* @author Steve Ebersole
* @author Emmanuel Bernard
@ -65,6 +70,29 @@ class MetadataContext {
return sessionFactory;
}
/**
* Retrieves the {@link Class java type} to {@link EntityType} map.
*
* @return The {@link Class java type} to {@link EntityType} map.
*/
public Map<Class<?>, EntityTypeImpl<?>> getEntityTypeMap() {
return Collections.unmodifiableMap( entityTypes );
}
public Map<Class<?>, EmbeddableTypeImpl<?>> getEmbeddableTypeMap() {
return Collections.unmodifiableMap( embeddables );
}
/*package*/ void registerEntityType(PersistentClass persistentClass, EntityTypeImpl<?> entityType) {
entityTypes.put( entityType.getBindableJavaType(), entityType );
entityTypesByEntityName.put( persistentClass.getEntityName(), entityType );
entityTypesByPersistentClass.put( persistentClass, entityType );
}
/*package*/ void registerEmbeddedableType(EmbeddableTypeImpl<?> embeddableType) {
embeddables.put( embeddableType.getJavaType(), embeddableType );
}
/**
* Given a Hibernate {@link PersistentClass}, locate the corresponding JPA {@link org.hibernate.type.EntityType}
* implementation. May retur null if the given {@link PersistentClass} has not yet been processed.
@ -98,29 +126,6 @@ class MetadataContext {
return entityTypesByEntityName.get( entityName );
}
/**
* Retrieves the {@link Class java type} to {@link EntityType} map.
*
* @return The {@link Class java type} to {@link EntityType} map.
*/
public Map<Class<?>, EntityTypeImpl<?>> getEntityTypeMap() {
return Collections.unmodifiableMap( entityTypes );
}
/*package*/ void registerEntityType(PersistentClass persistentClass, EntityTypeImpl<?> entityType) {
entityTypes.put( entityType.getBindableJavaType(), entityType );
entityTypesByEntityName.put( persistentClass.getEntityName(), entityType );
entityTypesByPersistentClass.put( persistentClass, entityType );
}
/*package*/ void registerEmbeddedableType(EmbeddableTypeImpl<?> embeddableType) {
embeddables.put( embeddableType.getJavaType(), embeddableType );
}
public Map<Class<?>, EmbeddableTypeImpl<?>> getEmbeddableTypeMap() {
return Collections.unmodifiableMap( embeddables );
}
@SuppressWarnings({ "unchecked" })
public void wrapUp() {
// IMPL NOTE : entityTypesByPersistentClass is a insertion-ordered map, where the insertion order
@ -135,7 +140,7 @@ class MetadataContext {
entry.getValue().getBuilder().addAttribute( attribute );
}
entry.getValue().lock();
// todo : find the X_ style metamodel classes, if present, and inject
populateStaticMetamodel( entry.getValue() );
}
}
@ -171,4 +176,34 @@ class MetadataContext {
return attributes;
}
private <X> void populateStaticMetamodel(AbstractManagedType<X> managedType) {
final Class<X> managedTypeClass = managedType.getJavaType();
final String metamodelClassName = managedTypeClass.getName() + "_";
try {
final Class metamodelClass = Class.forName( metamodelClassName, true, managedTypeClass.getClassLoader() );
// we found the class; so populate it...
registerAttributes( metamodelClass, managedType );
}
catch ( ClassNotFoundException ignore ) {
// nothing to do...
}
// todo : this does not account for @MappeSuperclass, mainly because this is not being tracked in our
// internal metamodel as populated from the annotatios properly
AbstractManagedType<? super X> superType = managedType.getSupertype();
if ( superType != null ) {
populateStaticMetamodel( superType );
}
}
private final Set<Class> processedMetamodelClasses = new HashSet<Class>();
private <X> void registerAttributes(Class metamodelClass, AbstractManagedType<X> managedType) {
if ( processedMetamodelClasses.add( metamodelClass ) ) {
return;
}
// push the attributes on to the metamodel class...
}
}

View File

@ -29,6 +29,11 @@ import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Join;
import org.hibernate.ejb.test.TestCase;
import org.hibernate.ejb.test.callbacks.VideoSystem;
import org.hibernate.ejb.test.callbacks.Television;
import org.hibernate.ejb.test.callbacks.RemoteControl;
import org.hibernate.ejb.test.inheritance.Fruit;
import org.hibernate.ejb.test.inheritance.Strawberry;
/**
* TODO : javadoc
@ -41,7 +46,14 @@ public class CriteriaCompilingTest extends TestCase {
Customer.class,
Item.class,
Order.class,
Product.class
Product.class,
// @Inheritance
Fruit.class,
Strawberry.class,
// @MappedSuperclass
VideoSystem.class,
Television.class,
RemoteControl.class
};
}