Author: epbernard
Date: 2009-10-29 14:57:24 -0400 (Thu, 29 Oct 2009)
New Revision: 17879
Added:
core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MappedSuperclassTypeImpl.java
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Animal.java
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Cat.java
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Cattish.java
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Dog.java
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Feline.java
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/SubThing.java
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Thing.java
Modified:
core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationBinder.java
core/trunk/annotations/src/main/java/org/hibernate/cfg/BinderHelper.java
core/trunk/annotations/src/main/java/org/hibernate/cfg/ClassPropertyHolder.java
core/trunk/core/src/main/java/org/hibernate/mapping/MappedSuperclass.java
core/trunk/core/src/main/java/org/hibernate/mapping/PersistentClass.java
core/trunk/core/src/main/java/org/hibernate/mapping/RootClass.java
core/trunk/core/src/main/java/org/hibernate/mapping/Subclass.java
core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/AbstractIdentifiableType.java
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-4533 Populate the JPA 2 metamodel with the new mapping.MappedSuperclass metadata
Modified: core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationBinder.java
===================================================================
---
core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationBinder.java 2009-10-29
17:22:00 UTC (rev 17878)
+++
core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationBinder.java 2009-10-29
18:57:24 UTC (rev 17879)
@@ -775,6 +775,21 @@
);
entityBinder.setIgnoreIdAnnotations( ignoreIdAnnotations );
persistentClass.setIdentifierMapper( mapper );
+
+ //If id definition is on a mapped superclass, update the mapping
+ final org.hibernate.mapping.MappedSuperclass superclass =
BinderHelper.getMappedSuperclassOrNull(
+ inferredData.getDeclaringClass(),
+ inheritanceStatePerClass,
+ mappings
+ );
+ if (superclass != null) {
+ superclass.setDeclaredIdentifierMapper(mapper);
+ }
+ else {
+ //we are for sure on the entity
+ persistentClass.setDeclaredIdentifierMapper( mapper );
+ }
+
Property property = new Property();
property.setName( "_identifierMapper" );
property.setNodeName( "id" );
@@ -1462,6 +1477,20 @@
Property prop = propBinder.bind();
propBinder.getSimpleValueBinder().setVersion(true);
rootClass.setVersion( prop );
+
+ //If version is on a mapped superclass, update the mapping
+ final org.hibernate.mapping.MappedSuperclass superclass =
BinderHelper.getMappedSuperclassOrNull(
+ inferredData.getDeclaringClass(),
+ inheritanceStatePerClass,
+ mappings
+ );
+ if (superclass != null) {
+ superclass.setDeclaredVersion(prop);
+ }
+ else {
+ //we know the property is on the actual entity
+ rootClass.setDeclaredVersion( prop );
+ }
SimpleValue simpleValue = (SimpleValue) prop.getValue();
simpleValue.setNullValue( "undefined" );
@@ -2202,6 +2231,19 @@
binder.setProperty( inferredData.getProperty() );
Property prop = binder.make();
rootClass.setIdentifierProperty( prop );
+ //if the id property is on a superclass, update the metamodel
+ final org.hibernate.mapping.MappedSuperclass superclass =
BinderHelper.getMappedSuperclassOrNull(
+ inferredData.getDeclaringClass(),
+ inheritanceStatePerClass,
+ mappings
+ );
+ if (superclass != null) {
+ superclass.setDeclaredIdentifierProperty(prop);
+ }
+ else {
+ //we know the property is on the actual entity
+ rootClass.setDeclaredIdentifierProperty( prop );
+ }
}
}
Modified: core/trunk/annotations/src/main/java/org/hibernate/cfg/BinderHelper.java
===================================================================
--- core/trunk/annotations/src/main/java/org/hibernate/cfg/BinderHelper.java 2009-10-29
17:22:00 UTC (rev 17878)
+++ core/trunk/annotations/src/main/java/org/hibernate/cfg/BinderHelper.java 2009-10-29
18:57:24 UTC (rev 17879)
@@ -60,6 +60,7 @@
import org.hibernate.mapping.Table;
import org.hibernate.mapping.ToOne;
import org.hibernate.mapping.Value;
+import org.hibernate.mapping.MappedSuperclass;
import org.hibernate.type.TypeFactory;
import org.hibernate.util.StringHelper;
import org.slf4j.Logger;
@@ -575,4 +576,24 @@
log.info( "Binding Any Meta definition: {}", defAnn.name() );
mappings.addAnyMetaDef( defAnn );
}
+
+ public static MappedSuperclass getMappedSuperclassOrNull(XClass declaringClass,
+ Map<XClass, InheritanceState> inheritanceStatePerClass,
+ ExtendedMappings mappings) {
+ boolean retrieve = false;
+ if ( declaringClass != null ) {
+ final InheritanceState inheritanceState = inheritanceStatePerClass.get( declaringClass
);
+ if ( inheritanceState == null ) {
+ throw new org.hibernate.annotations.common.AssertionFailure(
+ "Declaring class is not found in the inheritance state hierarchy: " +
declaringClass
+ );
+ }
+ if ( inheritanceState.isEmbeddableSuperclass ) {
+ retrieve = true;
+ }
+ }
+ return retrieve ?
+ mappings.getMappedSuperclass( mappings.getReflectionManager().toClass( declaringClass
) ) :
+ null;
+ }
}
Modified: core/trunk/annotations/src/main/java/org/hibernate/cfg/ClassPropertyHolder.java
===================================================================
---
core/trunk/annotations/src/main/java/org/hibernate/cfg/ClassPropertyHolder.java 2009-10-29
17:22:00 UTC (rev 17878)
+++
core/trunk/annotations/src/main/java/org/hibernate/cfg/ClassPropertyHolder.java 2009-10-29
18:57:24 UTC (rev 17879)
@@ -130,7 +130,7 @@
final ExtendedMappings mappings = getMappings();
final Class type = mappings.getReflectionManager().toClass( declaringClass );
MappedSuperclass superclass = mappings.getMappedSuperclass( type );
- superclass.addProperty( prop );
+ superclass.addDeclaredProperty( prop );
}
private void addPropertyToJoin(Property prop, XClass declaringClass, Join join) {
Modified: core/trunk/core/src/main/java/org/hibernate/mapping/MappedSuperclass.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/MappedSuperclass.java 2009-10-29
17:22:00 UTC (rev 17878)
+++ core/trunk/core/src/main/java/org/hibernate/mapping/MappedSuperclass.java 2009-10-29
18:57:24 UTC (rev 17879)
@@ -12,20 +12,27 @@
*
* Do not use outside this use case.
*
- * A proper redesign will be evluated in Hibernate 4
+ *
+ * A proper redesign will be evaluated in Hibernate 4
*
+ * Implementation details:
+ * properties are copies of their closest sub-persistentClass versions
+ *
* @author Emmanuel Bernard
*/
public class MappedSuperclass {
private final MappedSuperclass superMappedSuperclass;
private final PersistentClass superPersistentClass;
- private final List properties;
+ private final List declaredProperties;
private Class mappedClass;
+ private Property identifierProperty;
+ private Property version;
+ private Component identifierMapper;
public MappedSuperclass(MappedSuperclass superMappedSuperclass, PersistentClass
superPersistentClass) {
this.superMappedSuperclass = superMappedSuperclass;
this.superPersistentClass = superPersistentClass;
- this.properties = new ArrayList();
+ this.declaredProperties = new ArrayList();
}
/**
@@ -39,6 +46,14 @@
return superMappedSuperclass;
}
+ public boolean hasIdentifierProperty() {
+ return getIdentifierProperty() != null;
+ }
+
+ public boolean isVersioned() {
+ return getVersion() != null;
+ }
+
/**
* Returns the PersistentClass of the first superclass marked as @Entity
* or null if none exists
@@ -49,21 +64,21 @@
return superPersistentClass;
}
- public Iterator getPropertyIterator() {
- return properties.iterator();
+ public Iterator getDeclaredPropertyIterator() {
+ return declaredProperties.iterator();
}
- public void addProperty(Property p) {
+ public void addDeclaredProperty(Property p) {
//Do not add duplicate properties
//TODO is it efficient enough?
String name = p.getName();
- Iterator it = properties.iterator();
+ Iterator it = declaredProperties.iterator();
while (it.hasNext()) {
if ( name.equals( ((Property)it.next()).getName() ) ) {
return;
}
}
- properties.add(p);
+ declaredProperties.add(p);
}
public Class getMappedClass() {
@@ -73,4 +88,73 @@
public void setMappedClass(Class mappedClass) {
this.mappedClass = mappedClass;
}
+
+ public Property getIdentifierProperty() {
+ //get direct identifiermapper or the one from the super mappedSuperclass
+ // or the one from the super persistentClass
+ Property propagatedIdentifierProp = identifierProperty;
+ if ( propagatedIdentifierProp == null ) {
+ if ( superMappedSuperclass != null ) {
+ propagatedIdentifierProp = superMappedSuperclass.getIdentifierProperty();
+ }
+ if (propagatedIdentifierProp == null && superPersistentClass != null){
+ propagatedIdentifierProp = superPersistentClass.getIdentifierProperty();
+ }
+ }
+ return propagatedIdentifierProp;
+ }
+
+ public Property getDeclaredIdentifierProperty() {
+ return identifierProperty;
+ }
+
+ public void setDeclaredIdentifierProperty(Property prop) {
+ this.identifierProperty = prop;
+ }
+
+ public Property getVersion() {
+ //get direct version or the one from the super mappedSuperclass
+ // or the one from the super persistentClass
+ Property propagatedVersion = version;
+ if (propagatedVersion == null) {
+ if ( superMappedSuperclass != null ) {
+ propagatedVersion = superMappedSuperclass.getVersion();
+ }
+ if (propagatedVersion == null && superPersistentClass != null){
+ propagatedVersion = superPersistentClass.getVersion();
+ }
+ }
+ return propagatedVersion;
+ }
+
+ public Property getDeclaredVersion() {
+ return version;
+ }
+
+ public void setDeclaredVersion(Property prop) {
+ this.version = prop;
+ }
+
+ public Component getIdentifierMapper() {
+ //get direct identifiermapper or the one from the super mappedSuperclass
+ // or the one from the super persistentClass
+ Component propagatedMapper = identifierMapper;
+ if ( propagatedMapper == null ) {
+ if ( superMappedSuperclass != null ) {
+ propagatedMapper = superMappedSuperclass.getIdentifierMapper();
+ }
+ if (propagatedMapper == null && superPersistentClass != null){
+ propagatedMapper = superPersistentClass.getIdentifierMapper();
+ }
+ }
+ return propagatedMapper;
+ }
+
+ public Component getDeclaredIdentifierMapper() {
+ return identifierMapper;
+ }
+
+ public void setDeclaredIdentifierMapper(Component identifierMapper) {
+ this.identifierMapper = identifierMapper;
+ }
}
Modified: core/trunk/core/src/main/java/org/hibernate/mapping/PersistentClass.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/PersistentClass.java 2009-10-29
17:22:00 UTC (rev 17878)
+++ core/trunk/core/src/main/java/org/hibernate/mapping/PersistentClass.java 2009-10-29
18:57:24 UTC (rev 17879)
@@ -98,6 +98,7 @@
protected int optimisticLockMode;
private MappedSuperclass superMappedSuperclass;
+ private Component declaredIdentifierMapper;
public String getClassName() {
return className;
@@ -236,8 +237,10 @@
public abstract boolean isMutable();
public abstract boolean hasIdentifierProperty();
public abstract Property getIdentifierProperty();
+ public abstract Property getDeclaredIdentifierProperty();
public abstract KeyValue getIdentifier();
public abstract Property getVersion();
+ public abstract Property getDeclaredVersion();
public abstract Value getDiscriminator();
public abstract boolean isInherited();
public abstract boolean isPolymorphic();
@@ -776,6 +779,14 @@
return identifierMapper;
}
+ public Component getDeclaredIdentifierMapper() {
+ return declaredIdentifierMapper;
+ }
+
+ public void setDeclaredIdentifierMapper(Component declaredIdentifierMapper) {
+ this.declaredIdentifierMapper = declaredIdentifierMapper;
+ }
+
public boolean hasIdentifierMapper() {
return identifierMapper != null;
}
Modified: core/trunk/core/src/main/java/org/hibernate/mapping/RootClass.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/RootClass.java 2009-10-29 17:22:00
UTC (rev 17878)
+++ core/trunk/core/src/main/java/org/hibernate/mapping/RootClass.java 2009-10-29 18:57:24
UTC (rev 17879)
@@ -61,7 +61,9 @@
private Table table;
private boolean discriminatorInsertable = true;
private int nextSubclassId = 0;
-
+ private Property declaredIdentifierProperty;
+ private Property declaredVersion;
+
int nextSubclassId() {
return ++nextSubclassId;
}
@@ -80,6 +82,15 @@
public Property getIdentifierProperty() {
return identifierProperty;
}
+
+ public Property getDeclaredIdentifierProperty() {
+ return declaredIdentifierProperty;
+ }
+
+ public void setDeclaredIdentifierProperty(Property declaredIdentifierProperty) {
+ this.declaredIdentifierProperty = declaredIdentifierProperty;
+ }
+
public KeyValue getIdentifier() {
return identifier;
}
@@ -128,6 +139,15 @@
public Property getVersion() {
return version;
}
+
+ public Property getDeclaredVersion() {
+ return declaredVersion;
+ }
+
+ public void setDeclaredVersion(Property declaredVersion) {
+ this.declaredVersion = declaredVersion;
+ }
+
public void setVersion(Property version) {
this.version = version;
}
@@ -181,6 +201,7 @@
public void setIdentifierProperty(Property identifierProperty) {
this.identifierProperty = identifierProperty;
identifierProperty.setPersistentClass(this);
+
}
public void setMutable(boolean mutable) {
Modified: core/trunk/core/src/main/java/org/hibernate/mapping/Subclass.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/Subclass.java 2009-10-29 17:22:00
UTC (rev 17878)
+++ core/trunk/core/src/main/java/org/hibernate/mapping/Subclass.java 2009-10-29 18:57:24
UTC (rev 17879)
@@ -70,6 +70,11 @@
public Property getIdentifierProperty() {
return getSuperclass().getIdentifierProperty();
}
+
+ public Property getDeclaredIdentifierProperty() {
+ return null;
+ }
+
public KeyValue getIdentifier() {
return getSuperclass().getIdentifier();
}
@@ -143,6 +148,10 @@
return getSuperclass().getVersion();
}
+ public Property getDeclaredVersion() {
+ return null;
+ }
+
public boolean hasEmbeddedIdentifier() {
return getSuperclass().hasEmbeddedIdentifier();
}
Modified:
core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/AbstractIdentifiableType.java
===================================================================
---
core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/AbstractIdentifiableType.java 2009-10-29
17:22:00 UTC (rev 17878)
+++
core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/AbstractIdentifiableType.java 2009-10-29
18:57:24 UTC (rev 17879)
@@ -97,7 +97,19 @@
}
}
else {
- id_ = requireSupertype().getId( javaType );
+ //yuk yuk bad me
+ if (this instanceof MappedSuperclassTypeImpl) {
+ final AbstractIdentifiableType<? super X> supertype = getSupertype();
+ if (supertype != null) {
+ id_ = supertype.getId( javaType );
+ }
+ else {
+ id_ = null;
+ }
+ }
+ else {
+ id_ = requireSupertype().getId( javaType );
+ }
}
return id_;
}
@@ -227,6 +239,7 @@
return new Builder<X>() {
public void applyIdAttribute(SingularAttributeImpl<X, ?> idAttribute) {
AbstractIdentifiableType.this.id = idAttribute;
+ managedBuilder.addAttribute( idAttribute );
}
public void applyIdClassAttributes(Set<SingularAttribute<? super X,?>>
idClassAttributes) {
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-29
17:22:00 UTC (rev 17878)
+++
core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/AttributeFactory.java 2009-10-29
18:57:24 UTC (rev 17879)
@@ -54,19 +54,19 @@
}
@SuppressWarnings({ "unchecked" })
- public <X, Y> AttributeImplementor<X, Y>
buildAttribute(AbstractManagedType<X> ownerType, Property property) {
+ public <X, Y> AttributeImplementor<X, Y>
buildAttribute(AbstractManagedType<X> ownerType, Property property, boolean
getMember) {
AttributeContext attrContext = getAttributeContext( property );
final AttributeImplementor<X, Y> attribute;
if ( attrContext.isCollection() ) {
- attribute = buildPluralAttribute( ownerType, property, attrContext );
+ attribute = buildPluralAttribute( ownerType, property, attrContext, getMember );
}
else {
- final Type<Y> attrType = getType( ownerType, attrContext.getElementTypeStatus(),
attrContext.getElementValue() );
+ final Type<Y> attrType = getType( ownerType, attrContext.getElementTypeStatus(),
attrContext.getElementValue(), getMember );
attribute = new SingularAttributeImpl<X,Y>(
property.getName(),
property.getType().getReturnedClass(),
ownerType,
- determineStandardJavaMember( ownerType, property ),
+ getMember ? determineStandardJavaMember( ownerType, property ) : null,
false,
false,
property.isOptional(),
@@ -78,21 +78,21 @@
}
@SuppressWarnings( "unchecked" )
- private <X, Y, V, K> AttributeImplementor<X, Y>
buildPluralAttribute(AbstractManagedType<X> ownerType, Property property,
AttributeContext attrContext) {
+ private <X, Y, V, K> AttributeImplementor<X, Y>
buildPluralAttribute(AbstractManagedType<X> ownerType, Property property,
AttributeContext attrContext, boolean getMember) {
AttributeImplementor<X, Y> attribute;
- final Type<V> attrType = getType( ownerType, attrContext.getElementTypeStatus(),
attrContext.getElementValue() );
+ final Type<V> attrType = getType( ownerType, attrContext.getElementTypeStatus(),
attrContext.getElementValue(), getMember );
final Class<Y> collectionClass = (Class<Y>)
attrContext.getCollectionClass();
if ( java.util.Map.class.isAssignableFrom( collectionClass ) ) {
- final Type<K> keyType = getType( ownerType, attrContext.getKeyTypeStatus(),
attrContext.getKeyValue() );
+ final Type<K> keyType = getType( ownerType, attrContext.getKeyTypeStatus(),
attrContext.getKeyValue(), getMember );
attribute = PluralAttributeImpl.create( ownerType, attrType, collectionClass, keyType
)
- .member( determineStandardJavaMember( ownerType, property ) )
+ .member( getMember ? determineStandardJavaMember( ownerType, property ) : null )
.property( property )
.persistentAttributeType( attrContext.getElementAttributeType() )
.build();
}
else {
attribute = PluralAttributeImpl.create( ownerType, attrType, collectionClass, null )
- .member( determineStandardJavaMember( ownerType, property ) )
+ .member( getMember ? determineStandardJavaMember( ownerType, property ) : null )
.property( property )
.persistentAttributeType( attrContext.getElementAttributeType() )
.build();
@@ -100,13 +100,13 @@
return attribute;
}
- private <X> Type<X> getType(AbstractManagedType owner,
AttributeContext.TypeStatus elementTypeStatus, Value value) {
+ private <X> Type<X> getType(AbstractManagedType owner,
AttributeContext.TypeStatus elementTypeStatus, Value value, boolean getMember) {
final org.hibernate.type.Type type = value.getType();
switch ( elementTypeStatus ) {
case BASIC:
return buildBasicType( type );
case EMBEDDABLE:
- return buildEmbeddableType( owner, value, type );
+ return buildEmbeddableType( owner, value, type, getMember );
case ENTITY:
return buildEntityType( type );
default:
@@ -128,7 +128,7 @@
}
@SuppressWarnings( "unchecked" )
- private <X> Type<X> buildEmbeddableType(AbstractManagedType owner, Value
value, org.hibernate.type.Type type) {
+ private <X> Type<X> buildEmbeddableType(AbstractManagedType owner, Value
value, org.hibernate.type.Type type, boolean getMember) {
//build embedable type
final Class<X> clazz = type.getReturnedClass();
final EmbeddableTypeImpl<X> embeddableType = new EmbeddableTypeImpl<X>(
clazz, owner, (ComponentType) type );
@@ -137,22 +137,22 @@
final Iterator<Property> subProperties = component.getPropertyIterator();
while ( subProperties.hasNext() ) {
final Property property = subProperties.next();
- embeddableType.getBuilder().addAttribute( buildAttribute( embeddableType, property )
);
+ embeddableType.getBuilder().addAttribute( buildAttribute( embeddableType, property,
getMember ) );
}
embeddableType.lock();
return embeddableType;
}
@SuppressWarnings({ "unchecked" })
- public <X, Y> SingularAttributeImpl<X, Y>
buildIdAttribute(AbstractManagedType<X> ownerType, Property property) {
+ public <X, Y> SingularAttributeImpl<X, Y>
buildIdAttribute(AbstractManagedType<X> ownerType, Property property, boolean
getMember) {
final AttributeContext attrContext = getAttributeContext( property );
- final Type<Y> attrType = getType( ownerType, attrContext.getElementTypeStatus(),
attrContext.getElementValue() );
+ final Type<Y> attrType = getType( ownerType, attrContext.getElementTypeStatus(),
attrContext.getElementValue(), getMember );
final Class<Y> idJavaType = property.getType().getReturnedClass();
return new SingularAttributeImpl.Identifier(
property.getName(),
idJavaType,
ownerType,
- determineIdentifierJavaMember( ownerType, property ),
+ getMember ? determineIdentifierJavaMember( ownerType, property ) : null,
attrType,
attrContext.getElementAttributeType()
);
@@ -232,15 +232,15 @@
}
@SuppressWarnings({ "unchecked" })
- public <X, Y> SingularAttributeImpl<X, Y>
buildVerisonAttribute(AbstractManagedType<X> ownerType, Property property) {
+ public <X, Y> SingularAttributeImpl<X, Y>
buildVersionAttribute(AbstractManagedType<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() );
+ final Type<Y> attrType = getType( ownerType, attrContext.getElementTypeStatus(),
attrContext.getElementValue(), getMember );
return new SingularAttributeImpl.Version(
property.getName(),
javaType,
ownerType,
- determineVersionJavaMember( ownerType, property ),
+ getMember ? determineVersionJavaMember( ownerType, property ) : null,
attrType,
attrContext.getElementAttributeType()
);
@@ -252,7 +252,7 @@
// this should never happen, but to be safe...
throw new IllegalArgumentException( "Given property did not match declared
version property" );
}
- return entityMetamodel.getTuplizer( EntityMode.POJO
).getIdentifierGetter().getMember();
+ return entityMetamodel.getTuplizer( EntityMode.POJO ).getVersionGetter().getMember();
}
private static class AttributeContext {
Added:
core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MappedSuperclassTypeImpl.java
===================================================================
---
core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MappedSuperclassTypeImpl.java
(rev 0)
+++
core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MappedSuperclassTypeImpl.java 2009-10-29
18:57:24 UTC (rev 17879)
@@ -0,0 +1,21 @@
+package org.hibernate.ejb.metamodel;
+
+import javax.persistence.metamodel.MappedSuperclassType;
+import javax.persistence.metamodel.Type;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class MappedSuperclassTypeImpl<X> extends AbstractIdentifiableType<X>
implements MappedSuperclassType<X> {
+ public MappedSuperclassTypeImpl(
+ Class<X> javaType,
+ AbstractIdentifiableType<? super X> superType,
+ boolean hasIdentifierProperty,
+ boolean versioned) {
+ super( javaType, superType, hasIdentifierProperty, versioned );
+ }
+
+ public PersistenceType getPersistenceType() {
+ return PersistenceType.MAPPED_SUPERCLASS;
+ }
+}
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-29
17:22:00 UTC (rev 17878)
+++
core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetadataContext.java 2009-10-29
18:57:24 UTC (rev 17879)
@@ -25,16 +25,18 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
-import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
+import java.util.List;
+import java.util.ArrayList;
import javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.SingularAttribute;
-import javax.persistence.MappedSuperclass;
+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;
/**
* Defines a context for storing information during the building of the {@link
MetamodelImpl}.
@@ -53,14 +55,18 @@
private final SessionFactoryImplementor sessionFactory;
private final AttributeFactory attributeFactory = new AttributeFactory( this );
- private HashMap<Class<?>,EntityTypeImpl<?>> entityTypes
+ private Map<Class<?>,EntityTypeImpl<?>> entityTypes
= new HashMap<Class<?>, EntityTypeImpl<?>>();
- private HashMap<String,EntityTypeImpl<?>> entityTypesByEntityName
+ private Map<String,EntityTypeImpl<?>> entityTypesByEntityName
= new HashMap<String, EntityTypeImpl<?>>();
- private LinkedHashMap<PersistentClass,EntityTypeImpl<?>>
entityTypesByPersistentClass
- = new LinkedHashMap<PersistentClass,EntityTypeImpl<?>>();
- private HashMap<Class<?>, EmbeddableTypeImpl<?>> embeddables
+ private Map<PersistentClass,EntityTypeImpl<?>> entityTypesByPersistentClass
+ = new HashMap<PersistentClass,EntityTypeImpl<?>>();
+ private Map<Class<?>, EmbeddableTypeImpl<?>> embeddables
= new HashMap<Class<?>, EmbeddableTypeImpl<?>>();
+ private Map<MappedSuperclass, MappedSuperclassTypeImpl<?>>
mappedSuperclassByMappedSuperclassMapping
+ = new HashMap<MappedSuperclass,MappedSuperclassTypeImpl<?>>();
+ //this list contains MappedSuperclass and EntityTypes ordered by superclass first
+ private List<Object> orderedMappings = new ArrayList<Object>();
public MetadataContext(SessionFactoryImplementor sessionFactory) {
this.sessionFactory = sessionFactory;
@@ -87,12 +93,19 @@
entityTypes.put( entityType.getBindableJavaType(), entityType );
entityTypesByEntityName.put( persistentClass.getEntityName(), entityType );
entityTypesByPersistentClass.put( persistentClass, entityType );
+ orderedMappings.add( persistentClass );
}
/*package*/ void registerEmbeddedableType(EmbeddableTypeImpl<?> embeddableType) {
embeddables.put( embeddableType.getJavaType(), embeddableType );
}
+ /*package*/ void registerMappedSuperclassType(MappedSuperclass mappedSuperclass,
+ MappedSuperclassTypeImpl<?> mappedSuperclassType) {
+ mappedSuperclassByMappedSuperclassMapping.put( mappedSuperclass, mappedSuperclassType
);
+ orderedMappings.add( mappedSuperclass );
+ }
+
/**
* 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.
@@ -128,54 +141,120 @@
@SuppressWarnings({ "unchecked" })
public void wrapUp() {
- // IMPL NOTE : entityTypesByPersistentClass is a insertion-ordered map, where the
insertion order
- // ensures that a type's super type is already processed...
- for ( Map.Entry<PersistentClass,EntityTypeImpl<?>> entry :
entityTypesByPersistentClass.entrySet() ) {
- applyIdMetadata( entry.getKey(), entry.getValue() );
- applyVersionAttribute( entry.getKey(), entry.getValue() );
- Iterator<Property> properties = ( Iterator<Property> )
entry.getKey().getPropertyIterator();
- while ( properties.hasNext() ) {
- final Property property = properties.next();
- final Attribute attribute = attributeFactory.buildAttribute( entry.getValue(),
property );
- entry.getValue().getBuilder().addAttribute( attribute );
+ //we need to process types from superclasses to subclasses
+ for (Object mapping : orderedMappings) {
+ if ( PersistentClass.class.isAssignableFrom( mapping.getClass() ) ) {
+ @SuppressWarnings( "unchecked" )
+ final PersistentClass safeMapping = (PersistentClass) mapping;
+ final EntityTypeImpl<?> jpa2Mapping = entityTypesByPersistentClass.get(
safeMapping );
+ applyIdMetadata( safeMapping, jpa2Mapping );
+ applyVersionAttribute( safeMapping, jpa2Mapping );
+ Iterator<Property> properties = ( Iterator<Property> )
safeMapping.getDeclaredPropertyIterator();
+ while ( properties.hasNext() ) {
+ final Property property = properties.next();
+ final Attribute attribute = attributeFactory.buildAttribute( jpa2Mapping, property,
true );
+ jpa2Mapping.getBuilder().addAttribute( attribute );
+ }
+ jpa2Mapping.lock();
+ populateStaticMetamodel( jpa2Mapping );
}
- entry.getValue().lock();
- populateStaticMetamodel( entry.getValue() );
+ else if ( MappedSuperclass.class.isAssignableFrom( mapping.getClass() ) ) {
+ @SuppressWarnings( "unchecked" )
+ final MappedSuperclass safeMapping = (MappedSuperclass) mapping;
+ final MappedSuperclassTypeImpl<?> jpa2Mapping =
mappedSuperclassByMappedSuperclassMapping.get(
+ safeMapping
+ );
+ applyIdMetadata( safeMapping, jpa2Mapping );
+ applyVersionAttribute( safeMapping, jpa2Mapping );
+ Iterator<Property> properties = ( Iterator<Property> )
safeMapping.getDeclaredPropertyIterator();
+ while ( properties.hasNext() ) {
+ final Property property = properties.next();
+ final Attribute attribute = attributeFactory.buildAttribute( jpa2Mapping, property,
false );
+ jpa2Mapping.getBuilder().addAttribute( attribute );
+ }
+ jpa2Mapping.lock();
+ populateStaticMetamodel( jpa2Mapping );
+ }
+ else {
+ throw new AssertionFailure( "Unexpected mapping type: " +
mapping.getClass() );
+ }
}
}
private <X> void applyIdMetadata(PersistentClass persistentClass,
EntityTypeImpl<X> jpaEntityType) {
if ( persistentClass.hasIdentifierProperty() ) {
- jpaEntityType.getBuilder().applyIdAttribute(
- attributeFactory.buildIdAttribute( jpaEntityType,
persistentClass.getIdentifierProperty() )
- );
+ final Property declaredIdentifierProperty =
persistentClass.getDeclaredIdentifierProperty();
+ if (declaredIdentifierProperty != null) {
+ jpaEntityType.getBuilder().applyIdAttribute(
+ attributeFactory.buildIdAttribute( jpaEntityType, declaredIdentifierProperty, true
)
+ );
+ }
}
else {
jpaEntityType.getBuilder().applyIdClassAttributes( buildIdClassAttributes(
jpaEntityType, persistentClass ) );
}
}
+ private <X> void applyIdMetadata(MappedSuperclass mappingType,
MappedSuperclassTypeImpl<X> jpaMappingType) {
+ if ( mappingType.hasIdentifierProperty() ) {
+ final Property declaredIdentifierProperty =
mappingType.getDeclaredIdentifierProperty();
+ if (declaredIdentifierProperty != null) {
+ jpaMappingType.getBuilder().applyIdAttribute(
+ attributeFactory.buildIdAttribute( jpaMappingType, declaredIdentifierProperty,
false )
+ );
+ }
+ }
+ //an MappedSuperclass can have no identifier if the id is set below in the hierarchy
+ else if ( mappingType.getIdentifierMapper() != null ){
+ final Set<SingularAttribute<? super X, ?>> attributes =
buildIdClassAttributes(
+ jpaMappingType, mappingType
+ );
+ jpaMappingType.getBuilder().applyIdClassAttributes( attributes );
+ }
+ }
+
private <X> void applyVersionAttribute(PersistentClass persistentClass,
EntityTypeImpl<X> jpaEntityType) {
- if ( ! persistentClass.isVersioned() ) {
- return;
+ final Property declaredVersion = persistentClass.getDeclaredVersion();
+ if (declaredVersion != null) {
+ jpaEntityType.getBuilder().applyVersionAttribute(
+ attributeFactory.buildVersionAttribute( jpaEntityType, declaredVersion, true )
+ );
}
- jpaEntityType.getBuilder().applyVersionAttribute(
- attributeFactory.buildVerisonAttribute( jpaEntityType, persistentClass.getVersion()
)
- );
}
- @SuppressWarnings( "unchecked")
+ private <X> void applyVersionAttribute(MappedSuperclass mappingType,
MappedSuperclassTypeImpl<X> jpaMappingType) {
+ final Property declaredVersion = mappingType.getDeclaredVersion();
+ if ( declaredVersion != null ) {
+ jpaMappingType.getBuilder().applyVersionAttribute(
+ attributeFactory.buildVersionAttribute( jpaMappingType, declaredVersion, false )
+ );
+ }
+ }
+
private <X> Set<SingularAttribute<? super X, ?>>
buildIdClassAttributes(
EntityTypeImpl<X> jpaEntityType,
PersistentClass persistentClass) {
Set<SingularAttribute<? super X, ?>> attributes = new
HashSet<SingularAttribute<? super X, ?>>();
+ @SuppressWarnings( "unchecked")
Iterator<Property> properties =
persistentClass.getIdentifierMapper().getPropertyIterator();
while ( properties.hasNext() ) {
- attributes.add( attributeFactory.buildIdAttribute( jpaEntityType, properties.next() )
);
+ attributes.add( attributeFactory.buildIdAttribute( jpaEntityType, properties.next(),
true ) );
}
return attributes;
}
+ private <X> Set<SingularAttribute<? super X, ?>>
buildIdClassAttributes(
+ MappedSuperclassTypeImpl<X> jpaMappingType,
+ MappedSuperclass mappingType) {
+ Set<SingularAttribute<? super X, ?>> attributes = new
HashSet<SingularAttribute<? super X, ?>>();
+ @SuppressWarnings( "unchecked" )
+ Iterator<Property> properties =
mappingType.getIdentifierMapper().getPropertyIterator();
+ while ( properties.hasNext() ) {
+ attributes.add( attributeFactory.buildIdAttribute( jpaMappingType, properties.next(),
false ) );
+ }
+ return attributes;
+ }
+
private <X> void populateStaticMetamodel(AbstractManagedType<X> managedType)
{
final Class<X> managedTypeClass = managedType.getJavaType();
final String metamodelClassName = managedTypeClass.getName() + "_";
@@ -206,4 +285,7 @@
// push the attributes on to the metamodel class...
}
+ public MappedSuperclassTypeImpl<?> locateMappedSuperclassType(MappedSuperclass
mappedSuperclass) {
+ return mappedSuperclassByMappedSuperclassMapping.get(mappedSuperclass);
+ }
}
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-29
17:22:00 UTC (rev 17878)
+++
core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetamodelImpl.java 2009-10-29
18:57:24 UTC (rev 17879)
@@ -32,6 +32,7 @@
import javax.persistence.metamodel.EmbeddableType;
import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.MappedSuperclass;
import org.hibernate.engine.SessionFactoryImplementor;
/**
@@ -46,7 +47,7 @@
/**
* Build the metamodel using the information from the collection of Hibernate
- * {@link PersistentClass} models as well as the Hibernate {@link SessionFactory}.
+ * {@link PersistentClass} models as well as the Hibernate {@link
org.hibernate.SessionFactory}.
*
* @param persistentClasses Iterator over the Hibernate (config-time) metamodel
* @param sessionFactory The Hibernate session factry.
@@ -74,16 +75,24 @@
return entityType;
}
- @SuppressWarnings({ "unchecked" })
+ //TODO remove / reduce @SW scope
+ @SuppressWarnings( "unchecked" )
private static EntityTypeImpl<?> buildEntityType(PersistentClass persistentClass,
MetadataContext context) {
- final PersistentClass superPersistentClass = persistentClass.getSuperclass();
- final EntityTypeImpl superEntityType = superPersistentClass == null
+ final MappedSuperclass superMappedSuperclass =
persistentClass.getSuperMappedSuperclass();
+ AbstractIdentifiableType<?> superType = superMappedSuperclass == null
? null
- : locateOrBuildEntityType( superPersistentClass, context );
+ : locateOrBuildMappedsuperclassType( superMappedSuperclass, context );
+ //no mappedSuperclass, check for a super entity
+ if (superType == null) {
+ final PersistentClass superPersistentClass = persistentClass.getSuperclass();
+ superType = superPersistentClass == null
+ ? null
+ : locateOrBuildEntityType( superPersistentClass, context );
+ }
final Class javaType = persistentClass.getMappedClass();
EntityTypeImpl entityType = new EntityTypeImpl(
javaType,
- superEntityType,
+ superType,
persistentClass.getClassName(),
persistentClass.hasIdentifierProperty(),
persistentClass.isVersioned()
@@ -92,6 +101,41 @@
return entityType;
}
+ private static MappedSuperclassTypeImpl<?> locateOrBuildMappedsuperclassType(
+ MappedSuperclass mappedSuperclass, MetadataContext context) {
+ MappedSuperclassTypeImpl<?> mappedSuperclassType =
context.locateMappedSuperclassType( mappedSuperclass );
+ if ( mappedSuperclassType == null ) {
+ mappedSuperclassType = buildMappedSuperclassType(mappedSuperclass, context);
+ }
+ return mappedSuperclassType;
+ }
+
+ //TODO remove / reduce @SW scope
+ @SuppressWarnings( "unchecked" )
+ private static MappedSuperclassTypeImpl<?>
buildMappedSuperclassType(MappedSuperclass mappedSuperclass,
+ MetadataContext context) {
+ final MappedSuperclass superMappedSuperclass =
mappedSuperclass.getSuperMappedSuperclass();
+ AbstractIdentifiableType<?> superType = superMappedSuperclass == null
+ ? null
+ : locateOrBuildMappedsuperclassType( superMappedSuperclass, context );
+ //no mappedSuperclass, check for a super entity
+ if (superType == null) {
+ final PersistentClass superPersistentClass =
mappedSuperclass.getSuperPersistentClass();
+ superType = superPersistentClass == null
+ ? null
+ : locateOrBuildEntityType( superPersistentClass, context );
+ }
+ final Class javaType = mappedSuperclass.getMappedClass();
+ MappedSuperclassTypeImpl mappedSuperclassType = new MappedSuperclassTypeImpl(
+ javaType,
+ superType,
+ mappedSuperclass.hasIdentifierProperty(),
+ mappedSuperclass.isVersioned()
+ );
+ context.registerMappedSuperclassType( mappedSuperclass, mappedSuperclassType );
+ return mappedSuperclassType;
+ }
+
/**
* Instantiate the metamodel.
*
Added: core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Animal.java
===================================================================
--- core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Animal.java
(rev 0)
+++
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Animal.java 2009-10-29
18:57:24 UTC (rev 17879)
@@ -0,0 +1,31 @@
+package org.hibernate.ejb.test.metadata;
+
+import javax.persistence.MappedSuperclass;
+import javax.persistence.Id;
+import javax.persistence.GeneratedValue;
+
+/**
+ * @author Emmanuel Bernard
+ */
+@MappedSuperclass
+public class Animal extends SubThing {
+ private Long id;
+ private int legNbr;
+
+ @Id @GeneratedValue
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public int getLegNbr() {
+ return legNbr;
+ }
+
+ public void setLegNbr(int legNbr) {
+ this.legNbr = legNbr;
+ }
+}
Added: core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Cat.java
===================================================================
--- core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Cat.java
(rev 0)
+++
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Cat.java 2009-10-29
18:57:24 UTC (rev 17879)
@@ -0,0 +1,19 @@
+package org.hibernate.ejb.test.metadata;
+
+import javax.persistence.Entity;
+
+/**
+ * @author Emmanuel Bernard
+ */
+@Entity
+public class Cat extends Cattish {
+ private String nickname;
+
+ public String getNickname() {
+ return nickname;
+ }
+
+ public void setNickname(String nickname) {
+ this.nickname = nickname;
+ }
+}
Added:
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Cattish.java
===================================================================
--- core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Cattish.java
(rev 0)
+++
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Cattish.java 2009-10-29
18:57:24 UTC (rev 17879)
@@ -0,0 +1,19 @@
+package org.hibernate.ejb.test.metadata;
+
+import javax.persistence.MappedSuperclass;
+
+/**
+ * @author Emmanuel Bernard
+ */
+@MappedSuperclass
+public class Cattish extends Feline {
+ private long hoursOfSleep;
+
+ public long getHoursOfSleep() {
+ return hoursOfSleep;
+ }
+
+ public void setHoursOfSleep(long hoursOfSleep) {
+ this.hoursOfSleep = hoursOfSleep;
+ }
+}
Added: core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Dog.java
===================================================================
--- core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Dog.java
(rev 0)
+++
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Dog.java 2009-10-29
18:57:24 UTC (rev 17879)
@@ -0,0 +1,19 @@
+package org.hibernate.ejb.test.metadata;
+
+import javax.persistence.Entity;
+
+/**
+ * @author Emmanuel Bernard
+ */
+@Entity
+public class Dog extends Animal {
+ private String name;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
Added: core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Feline.java
===================================================================
--- core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Feline.java
(rev 0)
+++
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Feline.java 2009-10-29
18:57:24 UTC (rev 17879)
@@ -0,0 +1,19 @@
+package org.hibernate.ejb.test.metadata;
+
+import javax.persistence.Entity;
+
+/**
+ * @author Emmanuel Bernard
+ */
+@Entity
+public class Feline extends Animal {
+ private String color;
+
+ public String getColor() {
+ return color;
+ }
+
+ public void setColor(String color) {
+ this.color = color;
+ }
+}
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-29
17:22:00 UTC (rev 17878)
+++
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/MetadataTest.java 2009-10-29
18:57:24 UTC (rev 17879)
@@ -12,6 +12,9 @@
import javax.persistence.metamodel.PluralAttribute;
import javax.persistence.metamodel.MapAttribute;
import javax.persistence.metamodel.ListAttribute;
+import javax.persistence.metamodel.MappedSuperclassType;
+import javax.persistence.metamodel.CollectionAttribute;
+import javax.persistence.metamodel.IdentifiableType;
import org.hibernate.ejb.test.TestCase;
@@ -53,6 +56,8 @@
assertFalse( fridgeType.hasVersionAttribute() );
assertEquals( Type.PersistenceType.ENTITY, fridgeType.getPersistenceType() );
+ assertEquals( 3, fridgeType.getDeclaredAttributes().size() );
+
final EntityType<House> houseType = factory.getMetamodel().entity( House.class
);
assertTrue( houseType.hasSingleIdAttribute() );
final SingularAttribute<House, House.Key> houseId = houseType.getDeclaredId(
House.Key.class );
@@ -74,6 +79,7 @@
final SingularAttribute<? super FoodItem, Long> version = foodType.getVersion(
Long.class );
assertNotNull( version );
assertTrue( version.isVersion() );
+ assertEquals( 3, foodType.getDeclaredAttributes().size() );
}
@@ -158,15 +164,96 @@
assertEquals( PluralAttribute.CollectionType.LIST, roomsBySize.getCollectionType() );
}
- //todo test plural
+ public void testHierarchy() {
+ final EntityType<Cat> cat = factory.getMetamodel().entity( Cat.class );
+ assertNotNull( cat );
+ assertEquals( 7, cat.getAttributes().size() );
+ assertEquals( 1, cat.getDeclaredAttributes().size() );
+ assertTrue( cat.hasVersionAttribute() );
+ assertEquals( "version", cat.getVersion(Long.class).getName() );
+ verifyDeclaredVersiobnNotPresent( cat );
+ verifyDeclaredIdNotPresentAndIdPresent(cat);
+
+ assertEquals( Type.PersistenceType.MAPPED_SUPERCLASS,
cat.getSupertype().getPersistenceType() );
+ MappedSuperclassType<Cattish> cattish = (MappedSuperclassType<Cattish>)
cat.getSupertype();
+ assertEquals( 6, cattish.getAttributes().size() );
+ assertEquals( 1, cattish.getDeclaredAttributes().size() );
+
+ assertTrue( cattish.hasVersionAttribute() );
+ assertEquals( "version", cattish.getVersion(Long.class).getName() );
+ verifyDeclaredVersiobnNotPresent( cattish );
+ verifyDeclaredIdNotPresentAndIdPresent(cattish);
+
+ assertEquals( Type.PersistenceType.ENTITY, cattish.getSupertype().getPersistenceType()
);
+ EntityType<Feline> feline = (EntityType<Feline>) cattish.getSupertype();
+ assertEquals( 5, feline.getAttributes().size() );
+ assertEquals( 1, feline.getDeclaredAttributes().size() );
+
+ assertTrue( feline.hasVersionAttribute() );
+ assertEquals( "version", feline.getVersion(Long.class).getName() );
+ verifyDeclaredVersiobnNotPresent( feline );
+ verifyDeclaredIdNotPresentAndIdPresent(feline);
+
+ assertEquals( Type.PersistenceType.MAPPED_SUPERCLASS,
feline.getSupertype().getPersistenceType() );
+ MappedSuperclassType<Animal> animal = (MappedSuperclassType<Animal>)
feline.getSupertype();
+ assertEquals( 4, animal.getAttributes().size() );
+ assertEquals( 2, animal.getDeclaredAttributes().size() );
+
+ 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() );
+
+ 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() );
+ 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() );
+ assertNull( thing.getId( Long.class ) );
+
+ assertNull( thing.getSupertype() );
+ }
+
+ private void verifyDeclaredIdNotPresentAndIdPresent(IdentifiableType<?> type) {
+ assertEquals( "id", type.getId(Long.class).getName() );
+ try {
+ type.getDeclaredId(Long.class);
+ fail("Should not have a declared id");
+ }
+ catch (IllegalArgumentException e) {
+ //success
+ }
+ }
+
+ private void verifyDeclaredVersiobnNotPresent(IdentifiableType<?> type) {
+ try {
+ type.getDeclaredVersion(Long.class);
+ fail("Should not have a declared version");
+ }
+ catch (IllegalArgumentException e) {
+ //success
+ }
+ }
+
+ //todo test plural
+
@Override
public Class[] getAnnotatedClasses() {
return new Class[]{
Fridge.class,
FoodItem.class,
Person.class,
- House.class
+ House.class,
+ Dog.class,
+ Cat.class,
+ Cattish.class,
+ Feline.class
};
}
Added:
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/SubThing.java
===================================================================
--- core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/SubThing.java
(rev 0)
+++
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/SubThing.java 2009-10-29
18:57:24 UTC (rev 17879)
@@ -0,0 +1,17 @@
+package org.hibernate.ejb.test.metadata;
+
+/**
+ * @author Emmanuel Bernard
+ */
+//not an entity but in between mapped superclass and entity
+public class SubThing extends Thing {
+ private String blah;
+
+ public String getBlah() {
+ return blah;
+ }
+
+ public void setBlah(String blah) {
+ this.blah = blah;
+ }
+}
Added: core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Thing.java
===================================================================
--- core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Thing.java
(rev 0)
+++
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Thing.java 2009-10-29
18:57:24 UTC (rev 17879)
@@ -0,0 +1,30 @@
+package org.hibernate.ejb.test.metadata;
+
+import javax.persistence.MappedSuperclass;
+import javax.persistence.Version;
+
+/**
+ * @author Emmanuel Bernard
+ */
+@MappedSuperclass
+public class Thing {
+ private Double weight;
+ private Long version;
+
+ public Double getWeight() {
+ return weight;
+ }
+
+ public void setWeight(Double weight) {
+ this.weight = weight;
+ }
+
+ @Version
+ public Long getVersion() {
+ return version;
+ }
+
+ public void setVersion(Long version) {
+ this.version = version;
+ }
+}