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
public String toString() {
final StringBuilder sb = new StringBuilder();

View File

@ -80,6 +80,10 @@ public abstract class MappedAttribute implements Comparable<MappedAttribute> {
return typeParameters;
}
public Map<DotName, List<AnnotationInstance>> getAnnotations() {
return annotations;
}
/**
* 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.
*/
private final ColumnValues columnValues;
private ColumnValues columnValues;
public static SimpleAttribute createSimpleAttribute(String name, String type, Map<DotName, List<AnnotationInstance>> annotations) {
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) {
AnnotationInstance discriminatorOptionsAnnotation = JandexHelper.getSingleAnnotation(
annotations, JPADotNames.DISCRIMINATOR_COLUMN

View File

@ -114,6 +114,12 @@ public class ConfiguredClass {
*/
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> transientMethodNames = new HashSet<String>();
@ -134,7 +140,7 @@ public class ConfiguredClass {
this.associationAttributeMap = new TreeMap<String, AssociationAttribute>();
collectAttributes();
List<AttributeOverride> attributeOverrideList = findAttributeOverrides();
attributeOverrideMap = Collections.unmodifiableMap( findAttributeOverrides() );
}
public String getName() {
@ -185,6 +191,10 @@ public class ConfiguredClass {
return attribute;
}
public AttributeOverride geAttributeOverrideForPath(String propertyPath) {
return attributeOverrideMap.get( propertyPath );
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
@ -533,8 +543,8 @@ public class ConfiguredClass {
}
}
private List<AttributeOverride> findAttributeOverrides() {
List<AttributeOverride> attributeOverrideList = new ArrayList<AttributeOverride>();
private Map<String, AttributeOverride> findAttributeOverrides() {
Map<String, AttributeOverride> attributeOverrideList = new HashMap<String, AttributeOverride>();
AnnotationInstance attributeOverrideAnnotation = JandexHelper.getSingleAnnotation(
classInfo,
@ -542,7 +552,8 @@ public class ConfiguredClass {
);
if ( attributeOverrideAnnotation != null ) {
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(
@ -553,7 +564,8 @@ public class ConfiguredClass {
AnnotationInstance[] annotationInstances = attributeOverridesAnnotation.value().asNestedArray();
for ( AnnotationInstance annotationInstance : annotationInstances ) {
String prefix = createPathPrefix( annotationInstance );
attributeOverrideList.add( new AttributeOverride( prefix, annotationInstance ) );
AttributeOverride override = new AttributeOverride( prefix, annotationInstance );
attributeOverrideList.put( override.getAttributePath(), override );
}
}
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.JPADotNames;
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.SimpleAttribute;
import org.hibernate.metamodel.source.annotations.attribute.state.binding.AttributeBindingStateImpl;
@ -409,7 +410,7 @@ public class EntityBinder {
entityClass.getClassInfo(), JPADotNames.TABLE
);
if ( tableAnnotation != null ) {
schemaName = JandexHelper.getValue( tableAnnotation, "schema", String.class);
schemaName = JandexHelper.getValue( tableAnnotation, "schema", String.class );
catalogName = JandexHelper.getValue( tableAnnotation, "catalog", String.class );
String explicitTableName = JandexHelper.getValue( tableAnnotation, "name", String.class );
if ( StringHelper.isNotEmpty( explicitTableName ) ) {
@ -614,13 +615,15 @@ public class EntityBinder {
private void bindAttributes(EntityBinding entityBinding) {
// bind the attributes of this entity
AttributeContainer entity = entityBinding.getEntity();
bindAttributes( entityBinding, entity, entityClass );
bindAttributes( entityBinding, entity, entityClass, null );
// bind potential mapped super class attributes
ConfiguredClass childClass = entityClass;
ConfiguredClass parent = entityClass.getParent();
Hierarchical superTypeContainer = entityBinding.getEntity().getSuperType();
while ( containsPotentialMappedSuperclassAttributes( parent ) ) {
bindAttributes( entityBinding, superTypeContainer, parent );
bindAttributes( entityBinding, superTypeContainer, parent, childClass );
childClass = parent;
parent = parent.getParent();
superTypeContainer = superTypeContainer.getSuperType();
}
@ -631,8 +634,15 @@ public class EntityBinder {
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() ) {
String attributeName = simpleAttribute.getName();
if(childClass != null && childClass.geAttributeOverrideForPath(attributeName) != null) {
AttributeOverride override = childClass.geAttributeOverrideForPath(attributeName);
simpleAttribute = SimpleAttribute.createSimpleAttribute( simpleAttribute, override.getColumnValues() );
}
bindSingleMappedAttribute(
entityBinding,
attributeContainer,

View File

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