diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/attribute/AttributeOverride.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/attribute/AttributeOverride.java index b18e90bbd3..f2824f080b 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/attribute/AttributeOverride.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/attribute/AttributeOverride.java @@ -3,7 +3,9 @@ package org.hibernate.metamodel.source.annotations.attribute; import org.jboss.jandex.AnnotationInstance; import org.hibernate.AssertionFailure; +import org.hibernate.internal.util.StringHelper; import org.hibernate.metamodel.source.annotations.JPADotNames; +import org.hibernate.metamodel.source.annotations.util.JandexHelper; /** * Contains the information about a single {@link javax.persistence.AttributeOverride}. Instances of this class @@ -12,23 +14,34 @@ import org.hibernate.metamodel.source.annotations.JPADotNames; * @author Hardy Ferentschik */ public class AttributeOverride { + private static final String PROPERTY_PATH_SEPARATOR = "."; private final ColumnValues columnValues; private final String attributePath; public AttributeOverride(AnnotationInstance attributeOverrideAnnotation) { - this(null, attributeOverrideAnnotation); + this( null, attributeOverrideAnnotation ); } public AttributeOverride(String prefix, AnnotationInstance attributeOverrideAnnotation) { - if ( attributeOverrideAnnotation != null && !JPADotNames.ATTRIBUTE_OVERRIDE.equals( attributeOverrideAnnotation.name() ) ) { - throw new AssertionFailure( "A @Column annotation needs to be passed to the constructor" ); + if ( attributeOverrideAnnotation == null ) { + throw new IllegalArgumentException( "An AnnotationInstance needs to be passed" ); } + if ( !JPADotNames.ATTRIBUTE_OVERRIDE.equals( attributeOverrideAnnotation.name() ) ) { + throw new AssertionFailure( "A @AttributeOverride annotation needs to be passed to the constructor" ); + } - - - columnValues = null; - attributePath = ""; + columnValues = new ColumnValues( + JandexHelper.getValue( + attributeOverrideAnnotation, + "column", + AnnotationInstance.class + ) + ); + attributePath = createAttributePath( + prefix, + JandexHelper.getValue( attributeOverrideAnnotation, "name", String.class ) + ); } @Override @@ -68,6 +81,18 @@ public class AttributeOverride { result = 31 * result + ( attributePath != null ? attributePath.hashCode() : 0 ); return result; } + + private String createAttributePath(String prefix, String name) { + String path = ""; + if ( StringHelper.isNotEmpty( prefix ) ) { + path += prefix; + } + if ( StringHelper.isNotEmpty( path ) && !path.endsWith( PROPERTY_PATH_SEPARATOR ) ) { + path += PROPERTY_PATH_SEPARATOR; + } + path += name; + return path; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/entity/ConfiguredClass.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/entity/ConfiguredClass.java index a6241140c9..3cfe49a3e3 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/entity/ConfiguredClass.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/entity/ConfiguredClass.java @@ -54,6 +54,7 @@ import org.hibernate.HibernateException; import org.hibernate.metamodel.source.annotations.AnnotationBindingContext; 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.AttributeType; import org.hibernate.metamodel.source.annotations.attribute.MappedAttribute; import org.hibernate.metamodel.source.annotations.attribute.SimpleAttribute; @@ -93,16 +94,6 @@ public class ConfiguredClass { */ private final ConfiguredClassType configuredClassType; - /** - * The attribute overrides defined on this entity - */ - private final List attributeOverrides; - - /** - * The association overrides defined on this entity; - */ - private final List associationOverrides; - /** * The id attributes */ @@ -138,15 +129,12 @@ public class ConfiguredClass { this.clazz = context.classLoaderService().classForName( classInfo.toString() ); this.configuredClassType = determineType(); this.classAccessType = determineClassAccessType( defaultAccessType ); - - this.attributeOverrides = findAttributeOverrides(); - this.associationOverrides = findAssociationOverrides(); - this.simpleAttributeMap = new TreeMap(); this.idAttributeMap = new TreeMap(); this.associationAttributeMap = new TreeMap(); collectAttributes(); + List attributeOverrideList = findAttributeOverrides(); } public String getName() { @@ -545,29 +533,41 @@ public class ConfiguredClass { } } - private List findAttributeOverrides() { - List attributeOverrideList = new ArrayList(); + private List findAttributeOverrides() { + List attributeOverrideList = new ArrayList(); AnnotationInstance attributeOverrideAnnotation = JandexHelper.getSingleAnnotation( classInfo, JPADotNames.ATTRIBUTE_OVERRIDE ); if ( attributeOverrideAnnotation != null ) { - attributeOverrideList.add( attributeOverrideAnnotation ); + String prefix = createPathPrefix( attributeOverrideAnnotation ); + attributeOverrideList.add( new AttributeOverride( prefix, attributeOverrideAnnotation ) ); } AnnotationInstance attributeOverridesAnnotation = JandexHelper.getSingleAnnotation( classInfo, JPADotNames.ATTRIBUTE_OVERRIDES ); - if ( attributeOverrideAnnotation != null ) { - AnnotationInstance[] attributeOverride = attributeOverridesAnnotation.value().asNestedArray(); - Collections.addAll( attributeOverrideList, attributeOverride ); + if ( attributeOverridesAnnotation != null ) { + AnnotationInstance[] annotationInstances = attributeOverridesAnnotation.value().asNestedArray(); + for ( AnnotationInstance annotationInstance : annotationInstances ) { + String prefix = createPathPrefix( annotationInstance ); + attributeOverrideList.add( new AttributeOverride( prefix, annotationInstance ) ); + } } - return attributeOverrideList; } + private String createPathPrefix(AnnotationInstance attributeOverrideAnnotation) { + String prefix = null; + AnnotationTarget target = attributeOverrideAnnotation.target(); + if ( target instanceof FieldInfo || target instanceof MethodInfo ) { + prefix = JandexHelper.getPropertyName( target ); + } + return prefix; + } + private List findAssociationOverrides() { List associationOverrideList = new ArrayList(); diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/entity/MappedSuperclassWithAttributeOverrideTests.java b/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/entity/MappedSuperclassTests.java similarity index 68% rename from hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/entity/MappedSuperclassWithAttributeOverrideTests.java rename to hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/entity/MappedSuperclassTests.java index 53d50ce6a2..1801b3f88a 100644 --- a/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/entity/MappedSuperclassWithAttributeOverrideTests.java +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/entity/MappedSuperclassTests.java @@ -23,32 +23,41 @@ */ package org.hibernate.metamodel.source.annotations.entity; +import javax.persistence.AttributeOverride; +import javax.persistence.AttributeOverrides; +import javax.persistence.Embeddable; +import javax.persistence.Embedded; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.MappedSuperclass; import org.junit.Test; -import org.hibernate.action.internal.EntityIdentityInsertAction; import org.hibernate.metamodel.binding.AttributeBinding; import org.hibernate.metamodel.binding.EntityBinding; -import org.hibernate.metamodel.binding.EntityIdentifier; import org.hibernate.metamodel.domain.NonEntity; import org.hibernate.metamodel.domain.Superclass; +import org.hibernate.metamodel.relational.Column; +import org.hibernate.metamodel.relational.SimpleValue; +import org.hibernate.metamodel.relational.Tuple; +import org.hibernate.testing.FailureExpected; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertNotNull; import static junit.framework.Assert.assertTrue; /** - * Tests for {@code j.p.AttributeOverrides} and {@code j.p.AttributeOverride}. + * Tests for {@link javax.persistence.MappedSuperclass} {@link javax.persistence.AttributeOverrides} + * and {@code javax.persistence.AttributeOverride}. * * @author Hardy Ferentschik */ -public class MappedSuperclassWithAttributeOverrideTests extends BaseAnnotationBindingTestCase { +public class MappedSuperclassTests extends BaseAnnotationBindingTestCase { @Test + @FailureExpected(jiraKey = "HHH-6392", message = "work in progress") public void testMappedSuperclass() { - buildMetadataSources( MyMappedSuperClass.class, MyEntity.class ); + buildMetadataSources( MyMappedSuperClass.class, MyEntity.class, Address.class ); + EntityBinding binding = getEntityBinding( MyEntity.class ); assertEquals( "Wrong entity name", MyEntity.class.getName(), binding.getEntity().getName() ); assertEquals( @@ -56,10 +65,18 @@ public class MappedSuperclassWithAttributeOverrideTests extends BaseAnnotationBi MyMappedSuperClass.class.getName(), binding.getEntity().getSuperType().getName() ); + assertTrue( binding.getEntity().getSuperType() instanceof Superclass ); AttributeBinding nameBinding = binding.getAttributeBinding( "name" ); assertNotNull( "the name attribute should be bound to the subclass", nameBinding ); + assertTrue( "The binding should be a simple column", nameBinding.getValue() instanceof Tuple ); + Tuple tuple = (Tuple) nameBinding.getValue(); + SimpleValue value = tuple.values().iterator().next(); + assertTrue( value instanceof Column ); + Column column = (Column) value; + assertEquals( "Wrong column name", "MY_NAME", column.getColumnName().toString() ); + AttributeBinding idBinding = binding.getEntityIdentifier().getValueBinding(); assertNotNull( "the id attribute should be bound", idBinding ); } @@ -78,12 +95,24 @@ public class MappedSuperclassWithAttributeOverrideTests extends BaseAnnotationBi @Id private int id; String name; - int age; } @Entity + @AttributeOverrides( { + @AttributeOverride(name = "name", column = @javax.persistence.Column(name = "MY_NAME")), + @AttributeOverride(name = "address.street", column = @javax.persistence.Column(name = "MY_STREET")) + }) class MyEntity extends MyMappedSuperClass { private Long count; + @AttributeOverride(name = "city", column = @javax.persistence.Column(name = "MY_CITY")) + @Embedded + Address address; + } + + @Embeddable + class Address { + String street; + String city; } class NoEntity {