[hibernate-commits] Hibernate SVN: r17883 - in core/trunk/entitymanager/src: test/java/org/hibernate/ejb/test/metadata and 1 other directory.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Fri Oct 30 09:00:08 EDT 2009


Author: epbernard
Date: 2009-10-30 09:00:07 -0400 (Fri, 30 Oct 2009)
New Revision: 17883

Modified:
   core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/AttributeFactory.java
   core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetadataContext.java
   core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetamodelImpl.java
   core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/MetadataTest.java
Log:
HHH-4537 Add support for MappedSuperclassType Members in JPA 2

Modified: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/AttributeFactory.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/AttributeFactory.java	2009-10-30 11:49:13 UTC (rev 17882)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/AttributeFactory.java	2009-10-30 13:00:07 UTC (rev 17883)
@@ -27,6 +27,7 @@
 import java.util.Iterator;
 import javax.persistence.metamodel.Attribute;
 import javax.persistence.metamodel.Type;
+import javax.persistence.metamodel.IdentifiableType;
 
 import org.hibernate.EntityMode;
 import org.hibernate.type.EmbeddedComponentType;
@@ -38,6 +39,7 @@
 import org.hibernate.mapping.OneToMany;
 import org.hibernate.mapping.Property;
 import org.hibernate.mapping.Value;
+import org.hibernate.mapping.PersistentClass;
 import org.hibernate.tuple.entity.EntityMetamodel;
 
 /**
@@ -144,7 +146,7 @@
 	}
 
 	@SuppressWarnings({ "unchecked" })
-	public <X, Y> SingularAttributeImpl<X, Y> buildIdAttribute(AbstractManagedType<X> ownerType, Property property, boolean getMember) {
+	public <X, Y> SingularAttributeImpl<X, Y> buildIdAttribute(AbstractIdentifiableType<X> ownerType, Property property, boolean getMember) {
 		final AttributeContext attrContext = getAttributeContext( property );
 		final Type<Y> attrType = getType( ownerType, attrContext.getElementTypeStatus(), attrContext.getElementValue(), getMember );
 		final Class<Y> idJavaType = property.getType().getReturnedClass();
@@ -158,7 +160,7 @@
 		);
 	}
 
-	private Member determineIdentifierJavaMember(AbstractManagedType ownerType, Property property) {
+	private Member determineIdentifierJavaMember(IdentifiableType ownerType, Property property) {
 // see below
 //		final EntityMetamodel entityMetamodel = getDeclarerEntityMetamodel( property );
 		final EntityMetamodel entityMetamodel = getDeclarerEntityMetamodel( ownerType );
@@ -191,12 +193,26 @@
 //				.getEntityMetamodel();
 //	}
 // so we use the owner's java class to lookup the persister/entitymetamodel
-	private EntityMetamodel getDeclarerEntityMetamodel(AbstractManagedType ownerType) {
-		return context.getSessionFactory()
-				.getEntityPersister( ownerType.getJavaType().getName() )
+	private EntityMetamodel getDeclarerEntityMetamodel(IdentifiableType<?> ownerType) {
+	final Type.PersistenceType persistenceType = ownerType.getPersistenceType();
+	if ( persistenceType == Type.PersistenceType.ENTITY) {
+			return context.getSessionFactory()
+					.getEntityPersister( ownerType.getJavaType().getName() )
+					.getEntityMetamodel();
+		}
+		else if ( persistenceType == Type.PersistenceType.MAPPED_SUPERCLASS) {
+			PersistentClass persistentClass =
+					context.getPersistentClassHostingProperties( (MappedSuperclassTypeImpl<?>) ownerType );	
+			return context.getSessionFactory()
+				.getEntityPersister( persistentClass.getClassName() )
 				.getEntityMetamodel();
+		}
+		else {
+			throw new AssertionFailure( "Cannot get the metamodel for PersistenceType: " + persistenceType );
+		}
 	}
 
+
 // getting the owning PersistentClass from the Property is broken in certain cases with annotations...
 //	private Member determineStandardJavaMember(Property property) {
 //		final EntityMetamodel entityMetamodel = getDeclarerEntityMetamodel( property );
@@ -206,33 +222,39 @@
 //		return entityMetamodel.getTuplizer( EntityMode.POJO ).getGetter( index ).getMember();
 //	}
 // so we use the owner's java class to lookup the persister/entitymetamodel
-	private Member determineStandardJavaMember(AbstractManagedType ownerType, Property property) {
-		if ( Type.PersistenceType.EMBEDDABLE == ownerType.getPersistenceType() ) {
-			EmbeddableTypeImpl embeddableType = ( EmbeddableTypeImpl ) ownerType;
+	private Member determineStandardJavaMember(AbstractManagedType<?> ownerType, Property property) {
+	final Type.PersistenceType persistenceType = ownerType.getPersistenceType();
+	if ( Type.PersistenceType.EMBEDDABLE == persistenceType ) {
+			EmbeddableTypeImpl embeddableType = ( EmbeddableTypeImpl<?> ) ownerType;
 			return embeddableType.getHibernateType().getTuplizerMapping()
 					.getTuplizer( EntityMode.POJO )
 					.getGetter( embeddableType.getHibernateType().getPropertyIndex( property.getName() ) )
 					.getMember();
 		}
-		else if ( Type.PersistenceType.ENTITY == ownerType.getPersistenceType() ) {
-			final EntityMetamodel entityMetamodel = getDeclarerEntityMetamodel( ownerType );
-			final String propertyName = property.getName();
-			final Integer index = entityMetamodel.getPropertyIndexOrNull( propertyName );
-			if ( index == null ) {
-				// just like in #determineIdentifierJavaMember , this *should* indicate we have an IdClass mapping
-				return determineVirtualIdentifierJavaMember( entityMetamodel, property );
-			}
-			else {
-				return entityMetamodel.getTuplizer( EntityMode.POJO ).getGetter( index ).getMember();
-			}
+		else if ( Type.PersistenceType.ENTITY == persistenceType
+			|| Type.PersistenceType.MAPPED_SUPERCLASS == persistenceType ) {
+			return determineStandardJavaMemberOutOfIdentifiableType( (IdentifiableType<?>) ownerType, property );
 		}
 		else {
-			throw new IllegalArgumentException( "Unexpected owner type : " + ownerType.getPersistenceType() );
+			throw new IllegalArgumentException( "Unexpected owner type : " + persistenceType );
 		}
 	}
 
+	private Member determineStandardJavaMemberOutOfIdentifiableType(IdentifiableType<?> ownerType, Property property) {
+		final EntityMetamodel entityMetamodel = getDeclarerEntityMetamodel( ownerType );
+		final String propertyName = property.getName();
+		final Integer index = entityMetamodel.getPropertyIndexOrNull( propertyName );
+		if ( index == null ) {
+			// just like in #determineIdentifierJavaMember , this *should* indicate we have an IdClass mapping
+			return determineVirtualIdentifierJavaMember( entityMetamodel, property );
+		}
+		else {
+			return entityMetamodel.getTuplizer( EntityMode.POJO ).getGetter( index ).getMember();
+		}
+	}
+
 	@SuppressWarnings({ "unchecked" })
-	public <X, Y> SingularAttributeImpl<X, Y> buildVersionAttribute(AbstractManagedType<X> ownerType, Property property, boolean getMember) {
+	public <X, Y> SingularAttributeImpl<X, Y> buildVersionAttribute(AbstractIdentifiableType<X> ownerType, Property property, boolean getMember) {
 		final AttributeContext attrContext = getAttributeContext( property );
 		final Class<Y> javaType = property.getType().getReturnedClass();
 		final Type<Y> attrType = getType( ownerType, attrContext.getElementTypeStatus(), attrContext.getElementValue(), getMember );
@@ -246,7 +268,7 @@
 		);
 	}
 
-	private Member determineVersionJavaMember(AbstractManagedType ownerType, Property property) {
+	private Member determineVersionJavaMember(IdentifiableType ownerType, Property property) {
 		final EntityMetamodel entityMetamodel = getDeclarerEntityMetamodel( ownerType );
 		if ( ! property.getName().equals( entityMetamodel.getVersionProperty().getName() ) ) {
 			// this should never happen, but to be safe...

Modified: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetadataContext.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetadataContext.java	2009-10-30 11:49:13 UTC (rev 17882)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetadataContext.java	2009-10-30 13:00:07 UTC (rev 17883)
@@ -31,12 +31,14 @@
 import java.util.ArrayList;
 import javax.persistence.metamodel.Attribute;
 import javax.persistence.metamodel.SingularAttribute;
+import javax.swing.*;
 
 import org.hibernate.mapping.MappedSuperclass;
 import org.hibernate.mapping.PersistentClass;
 import org.hibernate.mapping.Property;
 import org.hibernate.engine.SessionFactoryImplementor;
 import org.hibernate.annotations.common.AssertionFailure;
+import org.hibernate.AnnotationException;
 
 /**
  * Defines a context for storing information during the building of the {@link MetamodelImpl}.
@@ -67,6 +69,14 @@
 			= new HashMap<MappedSuperclass,MappedSuperclassTypeImpl<?>>();
 	//this list contains MappedSuperclass and EntityTypes ordered by superclass first
 	private List<Object> orderedMappings = new ArrayList<Object>();
+	/**
+	 * Stack of PersistentClass being process. Last in the list is the highest in the stack.
+	 * 
+	 */
+	private List<PersistentClass> stackOfPersistentClassesBeingProcessed
+			= new ArrayList<PersistentClass>();
+	private Map<MappedSuperclassTypeImpl<?>, PersistentClass> mappedSuperClassTypeToPersistentClass
+			= new HashMap<MappedSuperclassTypeImpl<?>, PersistentClass>();
 
 	public MetadataContext(SessionFactoryImplementor sessionFactory) {
 		this.sessionFactory = sessionFactory;
@@ -104,6 +114,7 @@
 												  MappedSuperclassTypeImpl<?> mappedSuperclassType) {
 		mappedSuperclassByMappedSuperclassMapping.put( mappedSuperclass, mappedSuperclassType );
 		orderedMappings.add( mappedSuperclass );
+		mappedSuperClassTypeToPersistentClass.put( mappedSuperclassType, getEntityWorkedOn() );
 	}
 
 	/**
@@ -169,7 +180,7 @@
 				Iterator<Property> properties = ( Iterator<Property> ) safeMapping.getDeclaredPropertyIterator();
 				while ( properties.hasNext() ) {
 					final Property property = properties.next();
-					final Attribute attribute = attributeFactory.buildAttribute( jpa2Mapping, property, false );
+					final Attribute attribute = attributeFactory.buildAttribute( jpa2Mapping, property, true );
 					jpa2Mapping.getBuilder().addAttribute( attribute );
 				}
 				jpa2Mapping.lock();
@@ -200,7 +211,7 @@
 			final Property declaredIdentifierProperty = mappingType.getDeclaredIdentifierProperty();
 			if (declaredIdentifierProperty != null) {
 				jpaMappingType.getBuilder().applyIdAttribute(
-						attributeFactory.buildIdAttribute( jpaMappingType, declaredIdentifierProperty, false )
+						attributeFactory.buildIdAttribute( jpaMappingType, declaredIdentifierProperty, true )
 				);
 			}
 		}
@@ -226,7 +237,7 @@
 		final Property declaredVersion = mappingType.getDeclaredVersion();
 		if ( declaredVersion != null ) {
 			jpaMappingType.getBuilder().applyVersionAttribute(
-					attributeFactory.buildVersionAttribute( jpaMappingType, declaredVersion, false )
+					attributeFactory.buildVersionAttribute( jpaMappingType, declaredVersion, true )
 			);
 		}
 	}
@@ -250,7 +261,7 @@
 		@SuppressWarnings( "unchecked" )
 		Iterator<Property> properties = mappingType.getIdentifierMapper().getPropertyIterator();
 		while ( properties.hasNext() ) {
-			attributes.add( attributeFactory.buildIdAttribute( jpaMappingType, properties.next(), false ) );
+			attributes.add( attributeFactory.buildIdAttribute( jpaMappingType, properties.next(), true ) );
 		}
 		return attributes;
 	}
@@ -288,4 +299,33 @@
 	public MappedSuperclassTypeImpl<?> locateMappedSuperclassType(MappedSuperclass mappedSuperclass) {
 		return mappedSuperclassByMappedSuperclassMapping.get(mappedSuperclass);
 	}
+
+	public void pushEntityWorkedOn(PersistentClass persistentClass) {
+		stackOfPersistentClassesBeingProcessed.add(persistentClass);
+	}
+
+	public void popEntityWorkedOn(PersistentClass persistentClass) {
+		final PersistentClass stackTop = stackOfPersistentClassesBeingProcessed.remove(
+				stackOfPersistentClassesBeingProcessed.size() - 1
+		);
+		if (stackTop != persistentClass) {
+			throw new AssertionFailure( "Inconsistent popping: "
+				+ persistentClass.getEntityName() + " instead of " + stackTop.getEntityName() );
+		}
+	}
+
+	private PersistentClass getEntityWorkedOn() {
+		return stackOfPersistentClassesBeingProcessed.get(
+					stackOfPersistentClassesBeingProcessed.size() - 1
+			);
+	}
+
+	public PersistentClass getPersistentClassHostingProperties(MappedSuperclassTypeImpl<?> mappedSuperclassType) {
+		final PersistentClass persistentClass = mappedSuperClassTypeToPersistentClass.get( mappedSuperclassType );
+		if (persistentClass == null) {
+			throw new AssertionFailure( "Could not find PersistentClass for MappedSuperclassType: "
+					+ mappedSuperclassType.getJavaType() );
+		}
+		return persistentClass;
+	}
 }

Modified: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetamodelImpl.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetamodelImpl.java	2009-10-30 11:49:13 UTC (rev 17882)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetamodelImpl.java	2009-10-30 13:00:07 UTC (rev 17883)
@@ -78,6 +78,8 @@
 	//TODO remove / reduce @SW scope
 	@SuppressWarnings( "unchecked" )
 	private static EntityTypeImpl<?> buildEntityType(PersistentClass persistentClass, MetadataContext context) {
+		final Class javaType = persistentClass.getMappedClass();
+		context.pushEntityWorkedOn(persistentClass);
 		final MappedSuperclass superMappedSuperclass = persistentClass.getSuperMappedSuperclass();
 		AbstractIdentifiableType<?> superType = superMappedSuperclass == null
 				? null
@@ -89,7 +91,6 @@
 					? null
 					: locateOrBuildEntityType( superPersistentClass, context );
 		}
-		final Class javaType = persistentClass.getMappedClass();
 		EntityTypeImpl entityType = new EntityTypeImpl(
 				javaType,
 				superType,
@@ -98,6 +99,7 @@
 				persistentClass.isVersioned()
 		);
 		context.registerEntityType( persistentClass, entityType );
+		context.popEntityWorkedOn(persistentClass);
 		return entityType;
 	}
 

Modified: core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/MetadataTest.java
===================================================================
--- core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/MetadataTest.java	2009-10-30 11:49:13 UTC (rev 17882)
+++ core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/MetadataTest.java	2009-10-30 13:00:07 UTC (rev 17883)
@@ -169,6 +169,7 @@
 		assertNotNull( cat );
 		assertEquals( 7, cat.getAttributes().size() );
 		assertEquals( 1, cat.getDeclaredAttributes().size() );
+		ensureProperMember(cat.getDeclaredAttributes());
 
 		assertTrue( cat.hasVersionAttribute() );
 		assertEquals( "version", cat.getVersion(Long.class).getName() );
@@ -179,6 +180,7 @@
 		MappedSuperclassType<Cattish> cattish = (MappedSuperclassType<Cattish>) cat.getSupertype();
 		assertEquals( 6, cattish.getAttributes().size() );
 		assertEquals( 1, cattish.getDeclaredAttributes().size() );
+		ensureProperMember(cattish.getDeclaredAttributes());
 
 		assertTrue( cattish.hasVersionAttribute() );
 		assertEquals( "version", cattish.getVersion(Long.class).getName() );
@@ -189,6 +191,7 @@
 		EntityType<Feline> feline = (EntityType<Feline>) cattish.getSupertype();
 		assertEquals( 5, feline.getAttributes().size() );
 		assertEquals( 1, feline.getDeclaredAttributes().size() );
+		ensureProperMember(feline.getDeclaredAttributes());
 
 		assertTrue( feline.hasVersionAttribute() );
 		assertEquals( "version", feline.getVersion(Long.class).getName() );
@@ -199,27 +202,44 @@
 		MappedSuperclassType<Animal> animal = (MappedSuperclassType<Animal>) feline.getSupertype();
 		assertEquals( 4, animal.getAttributes().size() );
 		assertEquals( 2, animal.getDeclaredAttributes().size() );
+		ensureProperMember(animal.getDeclaredAttributes());
 
 		assertTrue( animal.hasVersionAttribute() );
 		assertEquals( "version", animal.getVersion(Long.class).getName() );
 		verifyDeclaredVersiobnNotPresent( animal );
 		assertEquals( "id", animal.getId(Long.class).getName() );
-		assertEquals( "id", animal.getDeclaredId(Long.class).getName() );
+		final SingularAttribute<Animal, Long> id = animal.getDeclaredId( Long.class );
+		assertEquals( "id", id.getName() );
+		assertNotNull( id.getJavaMember() );
 
 		assertEquals( Type.PersistenceType.MAPPED_SUPERCLASS, animal.getSupertype().getPersistenceType() );
 		MappedSuperclassType<Thing> thing = (MappedSuperclassType<Thing>) animal.getSupertype();
 		assertEquals( 2, thing.getAttributes().size() );
 		assertEquals( 2, thing.getDeclaredAttributes().size() );
+		ensureProperMember(thing.getDeclaredAttributes());
 		final SingularAttribute<Thing, Double> weight = thing.getDeclaredSingularAttribute( "weight", Double.class );
 		assertEquals( Double.class, weight.getJavaType() );
 
 		assertEquals( "version", thing.getVersion(Long.class).getName() );
-		assertEquals( "version", thing.getDeclaredVersion(Long.class).getName() );
+		final SingularAttribute<Thing, Long> version = thing.getDeclaredVersion( Long.class );
+		assertEquals( "version", version.getName() );
+		assertNotNull( version.getJavaMember() );
 		assertNull( thing.getId( Long.class ) );
 
 		assertNull( thing.getSupertype() );
 	}
 
+	private void ensureProperMember(Set<?> attributes) {
+		//we do not update the set so we are safe
+		@SuppressWarnings( "unchecked" )
+		final Set<Attribute<?, ?>> safeAttributes = ( Set<Attribute<?, ?>> ) attributes;
+		for (Attribute<?,?> attribute : safeAttributes ) {
+			final String name = attribute.getJavaMember().getName();
+			assertNotNull( attribute.getJavaMember() );
+			assertTrue( name.toLowerCase().endsWith( attribute.getName().toLowerCase() ) );
+		}
+	}
+
 	private void verifyDeclaredIdNotPresentAndIdPresent(IdentifiableType<?> type) {
 		assertEquals( "id", type.getId(Long.class).getName() );
 		try {



More information about the hibernate-commits mailing list