HHH-6392 Applying overrides for mapped superclasses
This commit is contained in:
parent
c2c3de9f90
commit
2500a70668
|
@ -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();
|
||||||
|
|
|
@ -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}
|
||||||
*
|
*
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -409,7 +410,7 @@ public class EntityBinder {
|
||||||
entityClass.getClassInfo(), JPADotNames.TABLE
|
entityClass.getClassInfo(), JPADotNames.TABLE
|
||||||
);
|
);
|
||||||
if ( tableAnnotation != null ) {
|
if ( tableAnnotation != null ) {
|
||||||
schemaName = JandexHelper.getValue( tableAnnotation, "schema", String.class);
|
schemaName = JandexHelper.getValue( tableAnnotation, "schema", String.class );
|
||||||
catalogName = JandexHelper.getValue( tableAnnotation, "catalog", String.class );
|
catalogName = JandexHelper.getValue( tableAnnotation, "catalog", String.class );
|
||||||
String explicitTableName = JandexHelper.getValue( tableAnnotation, "name", String.class );
|
String explicitTableName = JandexHelper.getValue( tableAnnotation, "name", String.class );
|
||||||
if ( StringHelper.isNotEmpty( explicitTableName ) ) {
|
if ( StringHelper.isNotEmpty( explicitTableName ) ) {
|
||||||
|
@ -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,
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
Loading…
Reference in New Issue