HHH-6392 Extracting the attribute overrides. Next step is to apply the overrides when creating the attribute bindings
This commit is contained in:
parent
1801faa1b3
commit
c2c3de9f90
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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 {
|
Loading…
Reference in New Issue