HHH-6392 Applying overrides for mapped superclasses

This commit is contained in:
Hardy Ferentschik 2011-07-11 23:13:18 +02:00
parent c2c3de9f90
commit 2500a70668
6 changed files with 52 additions and 13 deletions

View File

@ -44,6 +44,14 @@ public class AttributeOverride {
); );
} }
public ColumnValues getColumnValues() {
return columnValues;
}
public String getAttributePath() {
return attributePath;
}
@Override @Override
public String toString() { public String toString() {
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();

View File

@ -80,6 +80,10 @@ public abstract class MappedAttribute implements Comparable<MappedAttribute> {
return typeParameters; return typeParameters;
} }
public Map<DotName, List<AnnotationInstance>> getAnnotations() {
return annotations;
}
/** /**
* Returns the annotation with the specified name or {@code null} * Returns the annotation with the specified name or {@code null}
* *

View File

@ -84,12 +84,18 @@ public class SimpleAttribute extends MappedAttribute {
/** /**
* Defines the column values (relational values) for this property. * Defines the column values (relational values) for this property.
*/ */
private final ColumnValues columnValues; private ColumnValues columnValues;
public static SimpleAttribute createSimpleAttribute(String name, String type, Map<DotName, List<AnnotationInstance>> annotations) { public static SimpleAttribute createSimpleAttribute(String name, String type, Map<DotName, List<AnnotationInstance>> annotations) {
return new SimpleAttribute( name, type, annotations, false ); return new SimpleAttribute( name, type, annotations, false );
} }
public static SimpleAttribute createSimpleAttribute(SimpleAttribute simpleAttribute, ColumnValues columnValues) {
SimpleAttribute attribute = new SimpleAttribute( simpleAttribute.getName(), simpleAttribute.getType(), simpleAttribute.getAnnotations(), false );
attribute.columnValues = columnValues;
return attribute;
}
public static SimpleAttribute createDiscriminatorAttribute(Map<DotName, List<AnnotationInstance>> annotations) { public static SimpleAttribute createDiscriminatorAttribute(Map<DotName, List<AnnotationInstance>> annotations) {
AnnotationInstance discriminatorOptionsAnnotation = JandexHelper.getSingleAnnotation( AnnotationInstance discriminatorOptionsAnnotation = JandexHelper.getSingleAnnotation(
annotations, JPADotNames.DISCRIMINATOR_COLUMN annotations, JPADotNames.DISCRIMINATOR_COLUMN

View File

@ -114,6 +114,12 @@ public class ConfiguredClass {
*/ */
private final Map<String, EmbeddableClass> embeddedClasses = new HashMap<String, EmbeddableClass>(); private final Map<String, EmbeddableClass> embeddedClasses = new HashMap<String, EmbeddableClass>();
/**
* A map of all attribute overrides defined in this class. The override name is "normalised", meaning as if specified
* on class level. If the override is specified on attribute level the attribute name is used as prefix.
*/
private final Map<String, AttributeOverride> attributeOverrideMap;
private final Set<String> transientFieldNames = new HashSet<String>(); private final Set<String> transientFieldNames = new HashSet<String>();
private final Set<String> transientMethodNames = new HashSet<String>(); private final Set<String> transientMethodNames = new HashSet<String>();
@ -134,7 +140,7 @@ public class ConfiguredClass {
this.associationAttributeMap = new TreeMap<String, AssociationAttribute>(); this.associationAttributeMap = new TreeMap<String, AssociationAttribute>();
collectAttributes(); collectAttributes();
List<AttributeOverride> attributeOverrideList = findAttributeOverrides(); attributeOverrideMap = Collections.unmodifiableMap( findAttributeOverrides() );
} }
public String getName() { public String getName() {
@ -185,6 +191,10 @@ public class ConfiguredClass {
return attribute; return attribute;
} }
public AttributeOverride geAttributeOverrideForPath(String propertyPath) {
return attributeOverrideMap.get( propertyPath );
}
@Override @Override
public String toString() { public String toString() {
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
@ -533,8 +543,8 @@ public class ConfiguredClass {
} }
} }
private List<AttributeOverride> findAttributeOverrides() { private Map<String, AttributeOverride> findAttributeOverrides() {
List<AttributeOverride> attributeOverrideList = new ArrayList<AttributeOverride>(); Map<String, AttributeOverride> attributeOverrideList = new HashMap<String, AttributeOverride>();
AnnotationInstance attributeOverrideAnnotation = JandexHelper.getSingleAnnotation( AnnotationInstance attributeOverrideAnnotation = JandexHelper.getSingleAnnotation(
classInfo, classInfo,
@ -542,7 +552,8 @@ public class ConfiguredClass {
); );
if ( attributeOverrideAnnotation != null ) { if ( attributeOverrideAnnotation != null ) {
String prefix = createPathPrefix( attributeOverrideAnnotation ); String prefix = createPathPrefix( attributeOverrideAnnotation );
attributeOverrideList.add( new AttributeOverride( prefix, attributeOverrideAnnotation ) ); AttributeOverride override = new AttributeOverride( prefix, attributeOverrideAnnotation );
attributeOverrideList.put( override.getAttributePath(), override );
} }
AnnotationInstance attributeOverridesAnnotation = JandexHelper.getSingleAnnotation( AnnotationInstance attributeOverridesAnnotation = JandexHelper.getSingleAnnotation(
@ -553,7 +564,8 @@ public class ConfiguredClass {
AnnotationInstance[] annotationInstances = attributeOverridesAnnotation.value().asNestedArray(); AnnotationInstance[] annotationInstances = attributeOverridesAnnotation.value().asNestedArray();
for ( AnnotationInstance annotationInstance : annotationInstances ) { for ( AnnotationInstance annotationInstance : annotationInstances ) {
String prefix = createPathPrefix( annotationInstance ); String prefix = createPathPrefix( annotationInstance );
attributeOverrideList.add( new AttributeOverride( prefix, annotationInstance ) ); AttributeOverride override = new AttributeOverride( prefix, annotationInstance );
attributeOverrideList.put( override.getAttributePath(), override );
} }
} }
return attributeOverrideList; return attributeOverrideList;

View File

@ -67,6 +67,7 @@ import org.hibernate.metamodel.relational.UniqueKey;
import org.hibernate.metamodel.source.annotations.HibernateDotNames; import org.hibernate.metamodel.source.annotations.HibernateDotNames;
import org.hibernate.metamodel.source.annotations.JPADotNames; import org.hibernate.metamodel.source.annotations.JPADotNames;
import org.hibernate.metamodel.source.annotations.attribute.AssociationAttribute; import org.hibernate.metamodel.source.annotations.attribute.AssociationAttribute;
import org.hibernate.metamodel.source.annotations.attribute.AttributeOverride;
import org.hibernate.metamodel.source.annotations.attribute.MappedAttribute; import org.hibernate.metamodel.source.annotations.attribute.MappedAttribute;
import org.hibernate.metamodel.source.annotations.attribute.SimpleAttribute; import org.hibernate.metamodel.source.annotations.attribute.SimpleAttribute;
import org.hibernate.metamodel.source.annotations.attribute.state.binding.AttributeBindingStateImpl; import org.hibernate.metamodel.source.annotations.attribute.state.binding.AttributeBindingStateImpl;
@ -614,13 +615,15 @@ public class EntityBinder {
private void bindAttributes(EntityBinding entityBinding) { private void bindAttributes(EntityBinding entityBinding) {
// bind the attributes of this entity // bind the attributes of this entity
AttributeContainer entity = entityBinding.getEntity(); AttributeContainer entity = entityBinding.getEntity();
bindAttributes( entityBinding, entity, entityClass ); bindAttributes( entityBinding, entity, entityClass, null );
// bind potential mapped super class attributes // bind potential mapped super class attributes
ConfiguredClass childClass = entityClass;
ConfiguredClass parent = entityClass.getParent(); ConfiguredClass parent = entityClass.getParent();
Hierarchical superTypeContainer = entityBinding.getEntity().getSuperType(); Hierarchical superTypeContainer = entityBinding.getEntity().getSuperType();
while ( containsPotentialMappedSuperclassAttributes( parent ) ) { while ( containsPotentialMappedSuperclassAttributes( parent ) ) {
bindAttributes( entityBinding, superTypeContainer, parent ); bindAttributes( entityBinding, superTypeContainer, parent, childClass );
childClass = parent;
parent = parent.getParent(); parent = parent.getParent();
superTypeContainer = superTypeContainer.getSuperType(); superTypeContainer = superTypeContainer.getSuperType();
} }
@ -631,8 +634,15 @@ public class EntityBinder {
ConfiguredClassType.NON_ENTITY.equals( parent.getConfiguredClassType() ) ); ConfiguredClassType.NON_ENTITY.equals( parent.getConfiguredClassType() ) );
} }
private void bindAttributes(EntityBinding entityBinding, AttributeContainer attributeContainer, ConfiguredClass configuredClass) { private void bindAttributes(EntityBinding entityBinding, AttributeContainer attributeContainer, ConfiguredClass configuredClass, ConfiguredClass childClass) {
for ( SimpleAttribute simpleAttribute : configuredClass.getSimpleAttributes() ) { for ( SimpleAttribute simpleAttribute : configuredClass.getSimpleAttributes() ) {
String attributeName = simpleAttribute.getName();
if(childClass != null && childClass.geAttributeOverrideForPath(attributeName) != null) {
AttributeOverride override = childClass.geAttributeOverrideForPath(attributeName);
simpleAttribute = SimpleAttribute.createSimpleAttribute( simpleAttribute, override.getColumnValues() );
}
bindSingleMappedAttribute( bindSingleMappedAttribute(
entityBinding, entityBinding,
attributeContainer, attributeContainer,

View File

@ -48,13 +48,12 @@ import static junit.framework.Assert.assertTrue;
/** /**
* Tests for {@link javax.persistence.MappedSuperclass} {@link javax.persistence.AttributeOverrides} * Tests for {@link javax.persistence.MappedSuperclass} {@link javax.persistence.AttributeOverrides}
* and {@code javax.persistence.AttributeOverride}. * and {@link javax.persistence.AttributeOverride}.
* *
* @author Hardy Ferentschik * @author Hardy Ferentschik
*/ */
public class MappedSuperclassTests extends BaseAnnotationBindingTestCase { public class MappedSuperclassTests extends BaseAnnotationBindingTestCase {
@Test @Test
@FailureExpected(jiraKey = "HHH-6392", message = "work in progress")
public void testMappedSuperclass() { public void testMappedSuperclass() {
buildMetadataSources( MyMappedSuperClass.class, MyEntity.class, Address.class ); buildMetadataSources( MyMappedSuperClass.class, MyEntity.class, Address.class );
@ -75,7 +74,7 @@ public class MappedSuperclassTests extends BaseAnnotationBindingTestCase {
SimpleValue value = tuple.values().iterator().next(); SimpleValue value = tuple.values().iterator().next();
assertTrue( value instanceof Column ); assertTrue( value instanceof Column );
Column column = (Column) value; Column column = (Column) value;
assertEquals( "Wrong column name", "MY_NAME", column.getColumnName().toString() ); assertEquals( "Wrong column name", "`MY_NAME`", column.getColumnName().toString() );
AttributeBinding idBinding = binding.getEntityIdentifier().getValueBinding(); AttributeBinding idBinding = binding.getEntityIdentifier().getValueBinding();
assertNotNull( "the id attribute should be bound", idBinding ); assertNotNull( "the id attribute should be bound", idBinding );