HHH-6392 Extracting the attribute overrides. Next step is to apply the overrides when creating the attribute bindings

This commit is contained in:
Hardy Ferentschik 2011-07-11 18:41:54 +02:00
parent 1801faa1b3
commit c2c3de9f90
3 changed files with 88 additions and 34 deletions

View File

@ -3,7 +3,9 @@ package org.hibernate.metamodel.source.annotations.attribute;
import org.jboss.jandex.AnnotationInstance; import org.jboss.jandex.AnnotationInstance;
import org.hibernate.AssertionFailure; import org.hibernate.AssertionFailure;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.metamodel.source.annotations.JPADotNames; 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 * Contains the information about a single {@link javax.persistence.AttributeOverride}. Instances of this class
@ -12,6 +14,7 @@ import org.hibernate.metamodel.source.annotations.JPADotNames;
* @author Hardy Ferentschik * @author Hardy Ferentschik
*/ */
public class AttributeOverride { public class AttributeOverride {
private static final String PROPERTY_PATH_SEPARATOR = ".";
private final ColumnValues columnValues; private final ColumnValues columnValues;
private final String attributePath; private final String attributePath;
@ -20,15 +23,25 @@ public class AttributeOverride {
} }
public AttributeOverride(String prefix, AnnotationInstance attributeOverrideAnnotation) { public AttributeOverride(String prefix, AnnotationInstance attributeOverrideAnnotation) {
if ( attributeOverrideAnnotation != null && !JPADotNames.ATTRIBUTE_OVERRIDE.equals( attributeOverrideAnnotation.name() ) ) { if ( attributeOverrideAnnotation == null ) {
throw new AssertionFailure( "A @Column annotation needs to be passed to the constructor" ); 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 = new ColumnValues(
JandexHelper.getValue(
columnValues = null; attributeOverrideAnnotation,
attributePath = ""; "column",
AnnotationInstance.class
)
);
attributePath = createAttributePath(
prefix,
JandexHelper.getValue( attributeOverrideAnnotation, "name", String.class )
);
} }
@Override @Override
@ -68,6 +81,18 @@ public class AttributeOverride {
result = 31 * result + ( attributePath != null ? attributePath.hashCode() : 0 ); result = 31 * result + ( attributePath != null ? attributePath.hashCode() : 0 );
return result; 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;
}
} }

View File

@ -54,6 +54,7 @@ import org.hibernate.HibernateException;
import org.hibernate.metamodel.source.annotations.AnnotationBindingContext; import org.hibernate.metamodel.source.annotations.AnnotationBindingContext;
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.AttributeType; import org.hibernate.metamodel.source.annotations.attribute.AttributeType;
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;
@ -93,16 +94,6 @@ public class ConfiguredClass {
*/ */
private final ConfiguredClassType configuredClassType; private final ConfiguredClassType configuredClassType;
/**
* The attribute overrides defined on this entity
*/
private final List<AnnotationInstance> attributeOverrides;
/**
* The association overrides defined on this entity;
*/
private final List<AnnotationInstance> associationOverrides;
/** /**
* The id attributes * The id attributes
*/ */
@ -138,15 +129,12 @@ public class ConfiguredClass {
this.clazz = context.classLoaderService().classForName( classInfo.toString() ); this.clazz = context.classLoaderService().classForName( classInfo.toString() );
this.configuredClassType = determineType(); this.configuredClassType = determineType();
this.classAccessType = determineClassAccessType( defaultAccessType ); this.classAccessType = determineClassAccessType( defaultAccessType );
this.attributeOverrides = findAttributeOverrides();
this.associationOverrides = findAssociationOverrides();
this.simpleAttributeMap = new TreeMap<String, SimpleAttribute>(); this.simpleAttributeMap = new TreeMap<String, SimpleAttribute>();
this.idAttributeMap = new TreeMap<String, SimpleAttribute>(); this.idAttributeMap = new TreeMap<String, SimpleAttribute>();
this.associationAttributeMap = new TreeMap<String, AssociationAttribute>(); this.associationAttributeMap = new TreeMap<String, AssociationAttribute>();
collectAttributes(); collectAttributes();
List<AttributeOverride> attributeOverrideList = findAttributeOverrides();
} }
public String getName() { public String getName() {
@ -545,27 +533,39 @@ public class ConfiguredClass {
} }
} }
private List<AnnotationInstance> findAttributeOverrides() { private List<AttributeOverride> findAttributeOverrides() {
List<AnnotationInstance> attributeOverrideList = new ArrayList<AnnotationInstance>(); List<AttributeOverride> attributeOverrideList = new ArrayList<AttributeOverride>();
AnnotationInstance attributeOverrideAnnotation = JandexHelper.getSingleAnnotation( AnnotationInstance attributeOverrideAnnotation = JandexHelper.getSingleAnnotation(
classInfo, classInfo,
JPADotNames.ATTRIBUTE_OVERRIDE JPADotNames.ATTRIBUTE_OVERRIDE
); );
if ( attributeOverrideAnnotation != null ) { if ( attributeOverrideAnnotation != null ) {
attributeOverrideList.add( attributeOverrideAnnotation ); String prefix = createPathPrefix( attributeOverrideAnnotation );
attributeOverrideList.add( new AttributeOverride( prefix, attributeOverrideAnnotation ) );
} }
AnnotationInstance attributeOverridesAnnotation = JandexHelper.getSingleAnnotation( AnnotationInstance attributeOverridesAnnotation = JandexHelper.getSingleAnnotation(
classInfo, classInfo,
JPADotNames.ATTRIBUTE_OVERRIDES JPADotNames.ATTRIBUTE_OVERRIDES
); );
if ( attributeOverrideAnnotation != null ) { if ( attributeOverridesAnnotation != null ) {
AnnotationInstance[] attributeOverride = attributeOverridesAnnotation.value().asNestedArray(); AnnotationInstance[] annotationInstances = attributeOverridesAnnotation.value().asNestedArray();
Collections.addAll( attributeOverrideList, attributeOverride ); for ( AnnotationInstance annotationInstance : annotationInstances ) {
String prefix = createPathPrefix( annotationInstance );
attributeOverrideList.add( new AttributeOverride( prefix, annotationInstance ) );
}
}
return attributeOverrideList;
} }
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<AnnotationInstance> findAssociationOverrides() { private List<AnnotationInstance> findAssociationOverrides() {

View File

@ -23,32 +23,41 @@
*/ */
package org.hibernate.metamodel.source.annotations.entity; 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.Entity;
import javax.persistence.Id; import javax.persistence.Id;
import javax.persistence.MappedSuperclass; import javax.persistence.MappedSuperclass;
import org.junit.Test; import org.junit.Test;
import org.hibernate.action.internal.EntityIdentityInsertAction;
import org.hibernate.metamodel.binding.AttributeBinding; import org.hibernate.metamodel.binding.AttributeBinding;
import org.hibernate.metamodel.binding.EntityBinding; import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.EntityIdentifier;
import org.hibernate.metamodel.domain.NonEntity; import org.hibernate.metamodel.domain.NonEntity;
import org.hibernate.metamodel.domain.Superclass; 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.assertEquals;
import static junit.framework.Assert.assertNotNull; import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertTrue; 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 * @author Hardy Ferentschik
*/ */
public class MappedSuperclassWithAttributeOverrideTests 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 ); buildMetadataSources( MyMappedSuperClass.class, MyEntity.class, Address.class );
EntityBinding binding = getEntityBinding( MyEntity.class ); EntityBinding binding = getEntityBinding( MyEntity.class );
assertEquals( "Wrong entity name", MyEntity.class.getName(), binding.getEntity().getName() ); assertEquals( "Wrong entity name", MyEntity.class.getName(), binding.getEntity().getName() );
assertEquals( assertEquals(
@ -56,10 +65,18 @@ public class MappedSuperclassWithAttributeOverrideTests extends BaseAnnotationBi
MyMappedSuperClass.class.getName(), MyMappedSuperClass.class.getName(),
binding.getEntity().getSuperType().getName() binding.getEntity().getSuperType().getName()
); );
assertTrue( binding.getEntity().getSuperType() instanceof Superclass ); assertTrue( binding.getEntity().getSuperType() instanceof Superclass );
AttributeBinding nameBinding = binding.getAttributeBinding( "name" ); AttributeBinding nameBinding = binding.getAttributeBinding( "name" );
assertNotNull( "the name attribute should be bound to the subclass", nameBinding ); 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(); AttributeBinding idBinding = binding.getEntityIdentifier().getValueBinding();
assertNotNull( "the id attribute should be bound", idBinding ); assertNotNull( "the id attribute should be bound", idBinding );
} }
@ -78,12 +95,24 @@ public class MappedSuperclassWithAttributeOverrideTests extends BaseAnnotationBi
@Id @Id
private int id; private int id;
String name; String name;
int age;
} }
@Entity @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 { class MyEntity extends MyMappedSuperClass {
private Long count; 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 { class NoEntity {