From: <hib...@li...> - 2006-04-24 23:35:17
|
Author: epbernard Date: 2006-04-24 19:35:11 -0400 (Mon, 24 Apr 2006) New Revision: 9785 Added: trunk/HibernateExt/metadata/src/test/org/hibernate/test/reflection/java/xml/BusTrip.java trunk/HibernateExt/metadata/src/test/org/hibernate/test/reflection/java/xml/BusTripPk.java Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/reflection/java/EJB3OverridenAnnotationReader.java trunk/HibernateExt/metadata/src/java/org/hibernate/reflection/java/JavaXClass.java trunk/HibernateExt/metadata/src/java/org/hibernate/reflection/java/JavaXFactory.java trunk/HibernateExt/metadata/src/test/org/hibernate/test/reflection/java/xml/EJB3OverridenAnnotationReaderTest.java trunk/HibernateExt/metadata/src/test/org/hibernate/test/reflection/java/xml/metadata-complete.xml trunk/HibernateExt/metadata/src/test/org/hibernate/test/reflection/java/xml/orm.xml Log: XML overriding: support for <id> <embedded-id> Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/reflection/java/EJB3OverridenAnnotationReader.java =================================================================== --- trunk/HibernateExt/metadata/src/java/org/hibernate/reflection/java/EJB3OverridenAnnotationReader.java 2006-04-24 23:33:25 UTC (rev 9784) +++ trunk/HibernateExt/metadata/src/java/org/hibernate/reflection/java/EJB3OverridenAnnotationReader.java 2006-04-24 23:35:11 UTC (rev 9785) @@ -2,6 +2,7 @@ import java.beans.Introspector; import java.lang.annotation.Annotation; +import java.lang.reflect.AccessibleObject; import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Field; import java.lang.reflect.Method; @@ -25,6 +26,9 @@ import javax.persistence.ExcludeDefaultListeners; import javax.persistence.ExcludeSuperclassListeners; import javax.persistence.FieldResult; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; import javax.persistence.IdClass; import javax.persistence.Inheritance; import javax.persistence.InheritanceType; @@ -44,7 +48,13 @@ import javax.persistence.SqlResultSetMappings; import javax.persistence.Table; import javax.persistence.TableGenerator; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; import javax.persistence.UniqueConstraint; +import javax.persistence.EmbeddedId; +import javax.persistence.Lob; +import javax.persistence.Enumerated; +import javax.persistence.Basic; import org.dom4j.Attribute; import org.dom4j.Element; @@ -52,6 +62,7 @@ import org.hibernate.annotationfactory.AnnotationDescriptor; import org.hibernate.annotationfactory.AnnotationFactory; import org.hibernate.annotations.AccessType; +import org.hibernate.annotations.Columns; import org.hibernate.reflection.Filter; import org.hibernate.reflection.java.xml.XMLContext; import org.hibernate.util.ReflectHelper; @@ -106,16 +117,32 @@ annotationToXml.put( AttributeOverrides.class, "attribute-override" ); annotationToXml.put( AttributeOverride.class, "association-override" ); annotationToXml.put( AttributeOverrides.class, "association-override" ); + annotationToXml.put( Id.class, "id" ); + annotationToXml.put( EmbeddedId.class, "embedded-id" ); + annotationToXml.put( GeneratedValue.class, "generated-value" ); + annotationToXml.put( Column.class, "column" ); + annotationToXml.put( Columns.class, "column" ); + annotationToXml.put( Temporal.class, "temporal" ); + annotationToXml.put( Lob.class, "lob" ); + annotationToXml.put( Enumerated.class, "enumerated"); } private XMLContext xmlContext; private String className; private String propertyName; - private boolean isField; + private PropertyType propertyType; private boolean isFieldAccess; private transient Annotation[] annotations; private static final String WORD_SEPARATOR = "-"; + private transient List<Element> elementsForProperty; + private AccessibleObject mirroredAttribute; + private enum PropertyType { + PROPERTY, + FIELD, + METHOD + } + public EJB3OverridenAnnotationReader(AnnotatedElement el, XMLContext xmlContext) { super( el ); this.xmlContext = xmlContext; @@ -124,11 +151,21 @@ className = clazz.getName(); } else if ( el instanceof Field ) { - propertyName = ( (Field) el ).getName(); - isField = true; + Field field = (Field) el; + className = field.getDeclaringClass().getName(); + propertyName = field.getName(); + propertyType = PropertyType.FIELD; + String expectedGetter = "get" + Character.toUpperCase( propertyName.charAt( 0 ) ) + propertyName.substring( 1 ); + try { + mirroredAttribute = field.getDeclaringClass().getDeclaredMethod( expectedGetter ); + } + catch (NoSuchMethodException e) { + //no method + } } else if ( el instanceof Method ) { Method method = (Method) el; + className = method.getDeclaringClass().getName(); propertyName = method.getName(); if ( JavaXProperty.isProperty( method, @@ -138,12 +175,23 @@ if ( propertyName.startsWith( "get" ) ) { propertyName = Introspector.decapitalize( propertyName.substring( "get".length() ) ); } - if ( propertyName.startsWith( "is" ) ) { + else if ( propertyName.startsWith( "is" ) ) { propertyName = Introspector.decapitalize( propertyName.substring( "is".length() ) ); } - throw new RuntimeException( "Method " + propertyName + " is not a property getter" ); + else { + throw new RuntimeException( "Method " + propertyName + " is not a property getter" ); + } + propertyType = PropertyType.PROPERTY; + try { + mirroredAttribute = method.getDeclaringClass().getDeclaredField( propertyName ); + } + catch (NoSuchFieldException e) { + //no method + } } - isField = true; + else { + propertyType = PropertyType.METHOD; + } } else { className = null; @@ -175,7 +223,8 @@ private void initAnnotations() { if ( annotations == null ) { XMLContext.Default defaults = xmlContext.getDefault( className ); - if ( className != null ) { + if ( className != null && propertyName == null ) { + //is a class Element tree = xmlContext.getXMLTree( className, null ); Annotation[] annotations = super.getAnnotations(); List<Annotation> annotationList = new ArrayList<Annotation>( annotations.length + 5 ); @@ -227,9 +276,21 @@ if ( current != null ) annotationList.add( current ); this.annotations = annotationList.toArray( new Annotation[ annotationList.size() ] ); } - else if ( propertyName != null ) { - //TODO do it - this.annotations = super.getAnnotations(); + else if ( className != null && propertyName != null ) { + Element tree = xmlContext.getXMLTree( className, propertyName ); + Annotation[] annotations = super.getAnnotations(); + List<Annotation> annotationList = new ArrayList<Annotation>( annotations.length + 5 ); + for ( Annotation annotation : annotations ) { + if ( ! annotationToXml.containsKey( annotation.annotationType() ) ) { + //unknown annotations are left over + annotationList.add( annotation ); + } + } + preCalculateElementsForProperty(tree); + getId( annotationList, defaults ); + getEmbeddedId( annotationList, defaults ); + getBasic( annotationList, defaults ); + this.annotations = annotationList.toArray( new Annotation[ annotationList.size() ] ); } else { this.annotations = super.getAnnotations(); @@ -237,6 +298,210 @@ } } + private void getBasic(List<Annotation> annotationList, XMLContext.Default defaults) { + for (Element element : elementsForProperty) { + if ( "basic".equals( element.getName() ) ) { + boolean properAccessOnMetadataComplete = computeProperAccessOnMetadataComplete( defaults ); + boolean properOverridingOnMetadataNonComplete = computeProperOverridingOnMetadataComplete( defaults ); + if ( properAccessOnMetadataComplete || properOverridingOnMetadataNonComplete ) { + Annotation annotation = buildColumns( element ); + if (annotation != null) annotationList.add(annotation); + annotation = buildGeneratedValue(element); + if (annotation != null) annotationList.add(annotation); + annotation = buildTemporal(element); + if (annotation != null) annotationList.add(annotation); + //FIXME: fix the priority of xml over java for generator names + annotation = getTableGenerator( element, defaults ); + if (annotation != null) annotationList.add(annotation); + annotation = getSequenceGenerator( element, defaults ); + if (annotation != null) annotationList.add(annotation); + AnnotationDescriptor id = new AnnotationDescriptor( Id.class ); + annotationList.add( AnnotationFactory.create( id ) ); + } + else { + if ( defaults.canUseJavaAnnotations() ) { + if (! properOverridingOnMetadataNonComplete) { + //check that id exists on the other attribute + //TODO EmbeddedId too? + if (mirroredAttribute == null || ! mirroredAttribute.isAnnotationPresent( Id.class ) ) { + throw new AnnotationException("Cannot override an property with <id> it does not have an @Id already"); + } + } + } + } + } + } + if ( elementsForProperty.size() == 0 ) { + //we have nothing, so Java annotations might occurs + if ( defaults.canUseJavaAnnotations() ) { + Annotation annotation = super.getAnnotation( Basic.class ); + if (annotation != null) annotationList.add(annotation); + annotation = super.getAnnotation( Lob.class ); + if (annotation != null) annotationList.add(annotation); + annotation = super.getAnnotation( Enumerated.class ); + if (annotation != null) annotationList.add(annotation); + annotation = super.getAnnotation( Temporal.class ); + if (annotation != null) annotationList.add(annotation); + annotation = super.getAnnotation( Column.class ); + if (annotation != null) annotationList.add(annotation); + annotation = super.getAnnotation( Columns.class ); + if (annotation != null) annotationList.add(annotation); + } + } + } + + private void getEmbeddedId(List<Annotation> annotationList, XMLContext.Default defaults) { + for (Element element : elementsForProperty) { + if ( "embedded-id".equals( element.getName() ) ) { + boolean properAccessOnMetadataComplete = computeProperAccessOnMetadataComplete( defaults ); + boolean properOverridingOnMetadataNonComplete = computeProperOverridingOnMetadataComplete( defaults ); + if ( properAccessOnMetadataComplete || properOverridingOnMetadataNonComplete ) { + Annotation annotation = getAttributeOverrides( element, defaults ); + if (annotation != null) annotationList.add( annotation ); + annotation = getAssociationOverrides( element, defaults ); + if (annotation != null) annotationList.add( annotation ); + AnnotationDescriptor ad = new AnnotationDescriptor( EmbeddedId.class ); + annotationList.add( AnnotationFactory.create( ad ) ); + } + else { + if ( defaults.canUseJavaAnnotations() ) { + if (! properOverridingOnMetadataNonComplete) { + //check that id exists on the other attribute + //TODO Id too? + if (mirroredAttribute == null || ! mirroredAttribute.isAnnotationPresent( EmbeddedId.class ) ) { + throw new AnnotationException("Cannot override an property with <embedded-id> not having an @EmbeddedId already"); + } + } + } + } + } + } + } + + private void preCalculateElementsForProperty(Element tree) { + elementsForProperty = new ArrayList<Element>(); + Element element = tree != null ? tree.element( "attributes" ) : null; + for ( Element subelement : (List<Element>) element.elements() ) { + if ( propertyName.equals( subelement.attributeValue("name") ) ) { + elementsForProperty.add( subelement ); + } + } + } + + private void getId(List<Annotation> annotationList, XMLContext.Default defaults) { + for (Element element : elementsForProperty) { + if ( "id".equals( element.getName() ) ) { + boolean properAccessOnMetadataComplete = computeProperAccessOnMetadataComplete( defaults ); + boolean properOverridingOnMetadataNonComplete = computeProperOverridingOnMetadataComplete( defaults ); + if ( properAccessOnMetadataComplete || properOverridingOnMetadataNonComplete ) { + Annotation annotation = buildColumns( element ); + if (annotation != null) annotationList.add(annotation); + annotation = buildGeneratedValue(element); + if (annotation != null) annotationList.add(annotation); + annotation = buildTemporal(element); + if (annotation != null) annotationList.add(annotation); + //FIXME: fix the priority of xml over java for generator names + annotation = getTableGenerator( element, defaults ); + if (annotation != null) annotationList.add(annotation); + annotation = getSequenceGenerator( element, defaults ); + if (annotation != null) annotationList.add(annotation); + AnnotationDescriptor id = new AnnotationDescriptor( Id.class ); + annotationList.add( AnnotationFactory.create( id ) ); + } + else { + if ( defaults.canUseJavaAnnotations() ) { + if (! properOverridingOnMetadataNonComplete) { + //check that id exists on the other attribute + //TODO EmbeddedId too? + if (mirroredAttribute == null || ! mirroredAttribute.isAnnotationPresent( Id.class ) ) { + throw new AnnotationException("Cannot override an property with <id> it does not have an @Id already"); + } + } + } + } + } + } + } + + private boolean computeProperOverridingOnMetadataComplete(XMLContext.Default defaults) { + return defaults.canUseJavaAnnotations() + && super.isAnnotationPresent( Id.class ); + } + + private boolean computeProperAccessOnMetadataComplete(XMLContext.Default defaults) { + return (! defaults.canUseJavaAnnotations()) + && ( ( ! "field".equalsIgnoreCase( defaults.getAccess() ) && ! PropertyType.FIELD.equals( propertyType ) ) + || ( "field".equalsIgnoreCase( defaults.getAccess() ) && PropertyType.FIELD.equals( propertyType ) ) ); + } + + private Columns buildColumns(Element element) { + List<Element> subelements = element.elements( "column" ); + List<Column> columns = new ArrayList<Column>( subelements.size() ); + for (Element subelement : subelements) { + columns.add( getColumn( subelement, false ) ); + } + if ( columns.size() > 0 ) { + AnnotationDescriptor columnsDescr = new AnnotationDescriptor( Columns.class ); + columnsDescr.setValue( "columns", columns.toArray( new Column[ columns.size() ] ) ); + return AnnotationFactory.create( columnsDescr ); + } + else { + return null; + } + } + + private GeneratedValue buildGeneratedValue(Element element) { + Element subElement = element != null ? element.element( "generated-value" ) : null; + if (subElement != null) { + AnnotationDescriptor ad = new AnnotationDescriptor( GeneratedValue.class ); + String strategy = subElement.attributeValue( "strategy" ); + if ( "TABLE".equalsIgnoreCase( strategy ) ) { + ad.setValue( "strategy", GenerationType.TABLE ); + } + else if ( "SEQUENCE".equalsIgnoreCase( strategy ) ) { + ad.setValue( "strategy", GenerationType.SEQUENCE ); + } + else if ( "IDENTITY".equalsIgnoreCase( strategy ) ) { + ad.setValue( "strategy", GenerationType.IDENTITY ); + } + else if ( "AUTO".equalsIgnoreCase( strategy ) ) { + ad.setValue( "strategy", GenerationType.AUTO ); + } + else if ( StringHelper.isNotEmpty( strategy ) ) { + throw new AnnotationException( "Unknown GenerationType: " + strategy + ". " + SCHEMA_VALIDATION); + } + copyStringAttribute( ad, subElement, "generator", false ); + return AnnotationFactory.create( ad ); + } + else { + return null; + } + } + + private Temporal buildTemporal(Element element) { + Element subElement = element != null ? element.element( "temporal" ) : null; + if (subElement != null) { + AnnotationDescriptor ad = new AnnotationDescriptor( Temporal.class ); + String temporal = subElement.getTextTrim(); + if ( "DATE".equalsIgnoreCase( temporal ) ) { + ad.setValue( "value", TemporalType.DATE ); + } + else if ( "TIME".equalsIgnoreCase( temporal ) ) { + ad.setValue( "value", TemporalType.TIME ); + } + else if ( "TIMESTAMP".equalsIgnoreCase( temporal ) ) { + ad.setValue( "value", TemporalType.TIMESTAMP ); + } + else if ( StringHelper.isNotEmpty( temporal ) ) { + throw new AnnotationException( "Unknown TemporalType: " + temporal+ ". " + SCHEMA_VALIDATION); + } + return AnnotationFactory.create( ad ); + } + else { + return null; + } + } + private AssociationOverrides getAssociationOverrides(Element tree, XMLContext.Default defaults) { List<AssociationOverride> attributes = (List<AssociationOverride>) buildAssociationOverrides( tree ); if ( defaults.canUseJavaAnnotations() ) { @@ -336,7 +601,8 @@ for (Element current : subelements) { AnnotationDescriptor override = new AnnotationDescriptor( AttributeOverride.class ); copyStringAttribute( override, current, "name", true ); - override.setValue( "column", getColumn( current, true ) ); + Element column = current != null ? current.element( "column" ) : null; + override.setValue( "column", getColumn( column, true ) ); overrides.add( (AttributeOverride) AnnotationFactory.create( override ) ); } } @@ -344,23 +610,23 @@ } private Column getColumn(Element element, boolean isMandatory) { - Element subelement = element != null ? element.element( "column" ) : null; - if ( subelement != null ) { + //Element subelement = element != null ? element.element( "column" ) : null; + if ( element != null ) { AnnotationDescriptor column = new AnnotationDescriptor( Column.class ); - copyStringAttribute(column, subelement, "name", false); - copyBooleanAttribute(column, subelement, "unique"); - copyBooleanAttribute(column, subelement, "nullable"); - copyBooleanAttribute(column, subelement, "insertable"); - copyBooleanAttribute(column, subelement, "updatable"); - copyStringAttribute(column, subelement, "column-definition", false); - copyStringAttribute(column, subelement, "table", false); - copyIntegerAttribute(column, subelement, "length"); - copyIntegerAttribute(column, subelement, "precision"); - copyIntegerAttribute(column, subelement, "scale"); + copyStringAttribute(column, element, "name", false); + copyBooleanAttribute(column, element, "unique"); + copyBooleanAttribute(column, element, "nullable"); + copyBooleanAttribute(column, element, "insertable"); + copyBooleanAttribute(column, element, "updatable"); + copyStringAttribute(column, element, "column-definition", false); + copyStringAttribute(column, element, "table", false); + copyIntegerAttribute(column, element, "length"); + copyIntegerAttribute(column, element, "precision"); + copyIntegerAttribute(column, element, "scale"); return (Column) AnnotationFactory.create( column ); } else { - if ( isMandatory ) throw new AnnotationException( element.getPath() + ".column is mandatory. " + SCHEMA_VALIDATION); + if ( isMandatory ) throw new AnnotationException( element.getPath() + " is mandatory. " + SCHEMA_VALIDATION); return null; } } Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/reflection/java/JavaXClass.java =================================================================== --- trunk/HibernateExt/metadata/src/java/org/hibernate/reflection/java/JavaXClass.java 2006-04-24 23:33:25 UTC (rev 9784) +++ trunk/HibernateExt/metadata/src/java/org/hibernate/reflection/java/JavaXClass.java 2006-04-24 23:35:11 UTC (rev 9785) @@ -20,7 +20,7 @@ private final TypeEnvironment context; - public JavaXClass( Class clazz, TypeEnvironment env, JavaXFactory factory ) { + public JavaXClass(Class clazz, TypeEnvironment env, JavaXFactory factory) { super( clazz, factory ); this.context = env; } @@ -38,7 +38,7 @@ int length = classes.length; XClass[] xClasses = new XClass[length]; TypeEnvironment environment = getFactory().getTypeEnvironment( toClass() ); - for (int index = 0 ; index < length ; index++) { + for ( int index = 0; index < length ; index++ ) { xClasses[index] = getFactory().toXClass( classes[index], environment ); } return xClasses; @@ -62,17 +62,21 @@ private List<XProperty> getDeclaredFieldProperties(Filter filter) { List<XProperty> result = new LinkedList<XProperty>(); - for ( Field f : toClass().getDeclaredFields() ) - if ( JavaXProperty.isProperty( f, getTypeEnvironment().bind( f.getGenericType() ), filter ) ) + for ( Field f : toClass().getDeclaredFields() ) { + if ( JavaXProperty.isProperty( f, getTypeEnvironment().bind( f.getGenericType() ), filter ) ) { result.add( getFactory().getXProperty( f, this ) ); + } + } return result; } private List<XProperty> getDeclaredMethodProperties(Filter filter) { List<XProperty> result = new LinkedList<XProperty>(); - for ( Method m : toClass().getDeclaredMethods() ) - if ( JavaXProperty.isProperty( m, getTypeEnvironment().bind( m.getGenericReturnType() ), filter ) ) + for ( Method m : toClass().getDeclaredMethods() ) { + if ( JavaXProperty.isProperty( m, getTypeEnvironment().bind( m.getGenericReturnType() ), filter ) ) { result.add( getFactory().getXProperty( m, this ) ); + } + } return result; } @@ -81,10 +85,12 @@ } public List<XProperty> getDeclaredProperties(String accessType, Filter filter) { - if ( accessType.equals( ACCESS_FIELD ) ) - return getDeclaredFieldProperties(filter); - if ( accessType.equals( ACCESS_PROPERTY ) ) - return getDeclaredMethodProperties(filter); + if ( accessType.equals( ACCESS_FIELD ) ) { + return getDeclaredFieldProperties( filter ); + } + if ( accessType.equals( ACCESS_PROPERTY ) ) { + return getDeclaredMethodProperties( filter ); + } throw new IllegalArgumentException( "Unknown access type " + accessType ); } Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/reflection/java/JavaXFactory.java =================================================================== --- trunk/HibernateExt/metadata/src/java/org/hibernate/reflection/java/JavaXFactory.java 2006-04-24 23:33:25 UTC (rev 9784) +++ trunk/HibernateExt/metadata/src/java/org/hibernate/reflection/java/JavaXFactory.java 2006-04-24 23:35:11 UTC (rev 9785) @@ -66,6 +66,11 @@ xmlHelper = new XMLHelper(); entityResolver = XMLHelper.DEFAULT_DTD_RESOLVER; xmlContext = new XMLContext(); + xClasses.clear(); + packagesToXPackages.clear(); + xProperties.clear(); + xMethods.clear(); + } public XClass toXClass(Class clazz) { Added: trunk/HibernateExt/metadata/src/test/org/hibernate/test/reflection/java/xml/BusTrip.java =================================================================== --- trunk/HibernateExt/metadata/src/test/org/hibernate/test/reflection/java/xml/BusTrip.java 2006-04-24 23:33:25 UTC (rev 9784) +++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/reflection/java/xml/BusTrip.java 2006-04-24 23:35:11 UTC (rev 9785) @@ -0,0 +1,22 @@ +//$Id: $ +package org.hibernate.test.reflection.java.xml; + +import javax.persistence.Entity; +import javax.persistence.EmbeddedId; + +/** + * @author Emmanuel Bernard + */ +@Entity +public class BusTrip { + private BusTripPk id; + + @EmbeddedId + public BusTripPk getId() { + return id; + } + + public void setId(BusTripPk id) { + this.id = id; + } +} Added: trunk/HibernateExt/metadata/src/test/org/hibernate/test/reflection/java/xml/BusTripPk.java =================================================================== --- trunk/HibernateExt/metadata/src/test/org/hibernate/test/reflection/java/xml/BusTripPk.java 2006-04-24 23:33:25 UTC (rev 9784) +++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/reflection/java/xml/BusTripPk.java 2006-04-24 23:35:11 UTC (rev 9785) @@ -0,0 +1,26 @@ +//$Id: $ +package org.hibernate.test.reflection.java.xml; + +/** + * @author Emmanuel Bernard + */ +public class BusTripPk { + private String busNumber; + private String busDriver; + + public String getBusDriver() { + return busDriver; + } + + public void setBusDriver(String busDriver) { + this.busDriver = busDriver; + } + + public String getBusNumber() { + return busNumber; + } + + public void setBusNumber(String busNumber) { + this.busNumber = busNumber; + } +} Modified: trunk/HibernateExt/metadata/src/test/org/hibernate/test/reflection/java/xml/EJB3OverridenAnnotationReaderTest.java =================================================================== --- trunk/HibernateExt/metadata/src/test/org/hibernate/test/reflection/java/xml/EJB3OverridenAnnotationReaderTest.java 2006-04-24 23:33:25 UTC (rev 9784) +++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/reflection/java/xml/EJB3OverridenAnnotationReaderTest.java 2006-04-24 23:35:11 UTC (rev 9785) @@ -6,6 +6,8 @@ import java.io.InputStream; import java.util.ArrayList; import java.util.List; +import java.lang.reflect.Field; +import java.lang.reflect.Method; import javax.persistence.DiscriminatorColumn; import javax.persistence.DiscriminatorValue; import javax.persistence.Entity; @@ -27,6 +29,13 @@ import javax.persistence.ExcludeDefaultListeners; import javax.persistence.AttributeOverrides; import javax.persistence.AssociationOverrides; +import javax.persistence.Id; +import javax.persistence.Column; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import javax.persistence.EmbeddedId; import junit.framework.TestCase; import org.dom4j.DocumentException; @@ -35,6 +44,7 @@ import org.hibernate.reflection.java.EJB3OverridenAnnotationReader; import org.hibernate.reflection.java.xml.XMLContext; import org.hibernate.util.XMLHelper; +import org.hibernate.annotations.Columns; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.SAXNotSupportedException; @@ -156,6 +166,46 @@ assertNull( reader.getAnnotation( TableGenerator.class ) ); } + public void testIdRelatedAnnotations() throws Exception { + XMLContext context = buildContext("org/hibernate/test/reflection/java/xml/orm.xml"); + Method method = Administration.class.getDeclaredMethod( "getId" ); + EJB3OverridenAnnotationReader reader = new EJB3OverridenAnnotationReader(method, context); + assertNull( reader.getAnnotation( Id.class ) ); + assertNull( reader.getAnnotation( Column.class ) ); + Field field = Administration.class.getDeclaredField( "id" ); + reader = new EJB3OverridenAnnotationReader(field, context); + assertNotNull( reader.getAnnotation( Id.class ) ); + assertNotNull( reader.getAnnotation( GeneratedValue.class ) ); + assertEquals( GenerationType.SEQUENCE, reader.getAnnotation( GeneratedValue.class ).strategy() ); + assertEquals( "generator", reader.getAnnotation( GeneratedValue.class ).generator() ); + assertNotNull( reader.getAnnotation( SequenceGenerator.class ) ); + assertEquals( "seq", reader.getAnnotation( SequenceGenerator.class ).sequenceName() ); + assertNotNull( reader.getAnnotation( Columns.class ) ); + assertEquals( 1, reader.getAnnotation( Columns.class ).columns().length ); + assertEquals( "fld_id", reader.getAnnotation( Columns.class ).columns()[0].name() ); + assertNotNull( reader.getAnnotation( Temporal.class ) ); + assertEquals( TemporalType.DATE, reader.getAnnotation( Temporal.class ).value() ); + + context = buildContext("org/hibernate/test/reflection/java/xml/metadata-complete.xml"); + method = Administration.class.getDeclaredMethod( "getId" ); + reader = new EJB3OverridenAnnotationReader(method, context); + assertNotNull( "Default access type when not defined in metadata complete should be property", + reader.getAnnotation( Id.class ) ); + field = Administration.class.getDeclaredField( "id" ); + reader = new EJB3OverridenAnnotationReader(field, context); + assertNull( "Default access type when not defined in metadata complete should be property", + reader.getAnnotation( Id.class ) ); + + method = BusTrip.class.getDeclaredMethod( "getId" ); + reader = new EJB3OverridenAnnotationReader( method, context ); + assertNull( reader.getAnnotation( EmbeddedId.class ) ); + field = BusTrip.class.getDeclaredField( "id" ); + reader = new EJB3OverridenAnnotationReader( field, context ); + assertNotNull( reader.getAnnotation( EmbeddedId.class ) ); + assertNotNull( reader.getAnnotation( AttributeOverrides.class ) ); + assertEquals( 1, reader.getAnnotation( AttributeOverrides.class ).value().length ); + } + private XMLContext buildContext(String ormfile) throws SAXException, DocumentException, IOException { XMLHelper xmlHelper = new XMLHelper(); ClassLoader cl = Thread.currentThread().getContextClassLoader(); Modified: trunk/HibernateExt/metadata/src/test/org/hibernate/test/reflection/java/xml/metadata-complete.xml =================================================================== --- trunk/HibernateExt/metadata/src/test/org/hibernate/test/reflection/java/xml/metadata-complete.xml 2006-04-24 23:33:25 UTC (rev 9784) +++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/reflection/java/xml/metadata-complete.xml 2006-04-24 23:35:11 UTC (rev 9785) @@ -15,8 +15,30 @@ </persistence-unit-metadata> <package>org.hibernate.test.reflection.java.xml</package> <entity class="Administration"> + <attributes> + <id name="id"/> + </attributes> </entity> <entity class="Match"> </entity> <entity class="SocialSecurityMoralAccount"/> + <entity class="BusTrip" access="FIELD"> + <attributes> + <embedded-id name="id"> + <attribute-override name="busDriver"> + <column name="fld_busdriver"/> + </attribute-override> + </embedded-id> + </attributes> + </entity> + <embeddable class="BusTripPk" access="FIELD"> + <attributes> + <basic name="busDriver"> + <column name="busdriver"/> + </basic> + <basic name="busNumber"> + <column name="busnumber"/> + </basic> + </attributes> + </embeddable> </entity-mappings> \ No newline at end of file Modified: trunk/HibernateExt/metadata/src/test/org/hibernate/test/reflection/java/xml/orm.xml =================================================================== --- trunk/HibernateExt/metadata/src/test/org/hibernate/test/reflection/java/xml/orm.xml 2006-04-24 23:33:25 UTC (rev 9784) +++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/reflection/java/xml/orm.xml 2006-04-24 23:35:11 UTC (rev 9785) @@ -28,6 +28,14 @@ </secondary-table> <sequence-generator name="seqhilo" sequence-name="seqhilo"/> <table-generator name="table" table="tablehilo"/> + <attributes> + <id name="id"> + <column name="fld_id"/> + <generated-value generator="generator" strategy="SEQUENCE"/> + <temporal>DATE</temporal> + <sequence-generator name="generator" sequence-name="seq"/> + </id> + </attributes> </entity> <entity class="Match"> <inheritance strategy="JOINED"/> |