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 {