From: <hib...@li...> - 2006-04-27 21:12:45
|
Author: epbernard Date: 2006-04-27 17:12:40 -0400 (Thu, 27 Apr 2006) New Revision: 9821 Added: trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/Parent.java Modified: trunk/HibernateExt/metadata/doc/reference/en/modules/entity.xml trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AbstractPropertyHolder.java trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationBinder.java trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/ComponentPropertyHolder.java trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/PropertyHolder.java trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/collectionelement/CollectionElementTest.java trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/collectionelement/Toy.java trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/embedded/EmbeddedTest.java trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/embedded/Summary.java Log: ANN-40 support for @Parent and documentation if it Modified: trunk/HibernateExt/metadata/doc/reference/en/modules/entity.xml =================================================================== --- trunk/HibernateExt/metadata/doc/reference/en/modules/entity.xml 2006-04-27 17:14:58 UTC (rev 9820) +++ trunk/HibernateExt/metadata/doc/reference/en/modules/entity.xml 2006-04-27 21:12:40 UTC (rev 9821) @@ -2450,6 +2450,28 @@ return storyPart1; }</programlisting> </sect3> + + <sect3> + <title>@Parent</title> + + <para>When inside an embeddable object, you can define one of the + properties as a pointer back to the owner element.</para> + + <programlisting>@Entity +public class Person { + @Embeddable public Address address; + ... +} + +@Embeddable +public class Address { + @Parent public Person owner; + ... +} + + +person == person.address.owner</programlisting> + </sect3> </sect2> <sect2> @@ -2662,6 +2684,7 @@ public class Toy { public String name; public String serial; + public Boy owner; public String getName() { return name; @@ -2679,6 +2702,15 @@ this.serial = serial; } + <emphasis role="bold">@Parent</emphasis> + public Boy getOwner() { + return owner; + } + + public void setOwner(Boy owner) { + this.owner = owner; + } + public boolean equals(Object o) { if ( this == o ) return true; if ( o == null || getClass() != o.getClass() ) return false; @@ -2699,6 +2731,11 @@ } }</programlisting> + <para>On a collection of embeddable objects, the embeddable object can + have a proeprty annotated with <literal>@Parent</literal>. This + property will then point back to the entity containing the + collection.</para> + <note> <para>Previous versions of Hibernate Annotations used the <literal>@OneToMany</literal> to mark a collection of elements. Due Added: trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/Parent.java =================================================================== --- trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/Parent.java 2006-04-27 17:14:58 UTC (rev 9820) +++ trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/Parent.java 2006-04-27 21:12:40 UTC (rev 9821) @@ -0,0 +1,18 @@ +//$Id: $ +package org.hibernate.annotations; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import java.lang.annotation.Retention; +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Target; + +/** + * Reference the property as a pointer back to the owner (generally the owning entity) + * + * @author Emmanuel Bernard + */ +@Target({METHOD, FIELD}) +@Retention(RUNTIME) +public @interface Parent { +} Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AbstractPropertyHolder.java =================================================================== --- trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AbstractPropertyHolder.java 2006-04-27 17:14:58 UTC (rev 9820) +++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AbstractPropertyHolder.java 2006-04-27 21:12:40 UTC (rev 9821) @@ -17,6 +17,7 @@ import org.hibernate.reflection.XClass; import org.hibernate.reflection.XProperty; import org.hibernate.util.StringHelper; +import org.hibernate.AssertionFailure; /** * @author Emmanuel Bernard @@ -180,4 +181,8 @@ } return columnOverride; } + + public void setParentProperty(String parentProperty) { + throw new AssertionFailure("Setting the parent property to a non component"); + } } Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationBinder.java =================================================================== --- trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationBinder.java 2006-04-27 17:14:58 UTC (rev 9820) +++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationBinder.java 2006-04-27 21:12:40 UTC (rev 9821) @@ -81,6 +81,7 @@ import org.hibernate.annotations.TypeDef; import org.hibernate.annotations.TypeDefs; import org.hibernate.annotations.Where; +import org.hibernate.annotations.Parent; import org.hibernate.cfg.annotations.CollectionBinder; import org.hibernate.cfg.annotations.EntityBinder; import org.hibernate.cfg.annotations.Nullability; @@ -967,6 +968,17 @@ ); } + if ( property.isAnnotationPresent( Parent.class ) ) { + if ( propertyHolder.isComponent() ) { + propertyHolder.setParentProperty( property.getName() ); + } + else { + throw new AnnotationException("@Parent cannot be applied outside an embeddable object: " + + StringHelper.qualify( propertyHolder.getPath(), property.getName() ) ); + } + return; + } + //process @JoinColumn(s) before @Column(s) to handle collection of elements properly { JoinColumn[] anns = null; @@ -1085,9 +1097,9 @@ localGenerators.putAll( buildLocalGenerators( property, mappings ) ); //manage composite related metadata - Embeddable embeddableAnn = returnedClass.getAnnotation( Embeddable.class ); //guess if its a component and find id data access (property, field etc) - final boolean isComponent = embeddableAnn != null || property.isAnnotationPresent( EmbeddedId.class ); + final boolean isComponent = returnedClass.isAnnotationPresent( Embeddable.class ) + || property.isAnnotationPresent( EmbeddedId.class ); boolean propertyAnnotated = entityBinder.isPropertyAnnotated( returnedClass ); String propertyAccessor = entityBinder.getPropertyAccessor( returnedClass ); //if ( isComponent && embeddableAnn != null && embeddableAnn.access() == AccessType.FIELD ) propertyAccess = false; Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/ComponentPropertyHolder.java =================================================================== --- trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/ComponentPropertyHolder.java 2006-04-27 17:14:58 UTC (rev 9820) +++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/ComponentPropertyHolder.java 2006-04-27 21:12:40 UTC (rev 9821) @@ -80,6 +80,10 @@ return true; } + public void setParentProperty(String parentProperty) { + component.setParentProperty( parentProperty ); + } + @Override public Column[] getOverriddenColumn(String propertyName) { //FIXME this is yukky Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/PropertyHolder.java =================================================================== --- trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/PropertyHolder.java 2006-04-27 17:14:58 UTC (rev 9820) +++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/PropertyHolder.java 2006-04-27 21:12:40 UTC (rev 9821) @@ -26,6 +26,8 @@ boolean isComponent(); + void setParentProperty(String parentProperty); + String getPath(); /** Modified: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/collectionelement/CollectionElementTest.java =================================================================== --- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/collectionelement/CollectionElementTest.java 2006-04-27 17:14:58 UTC (rev 9820) +++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/collectionelement/CollectionElementTest.java 2006-04-27 21:12:40 UTC (rev 9821) @@ -65,6 +65,7 @@ boy = (Boy) s.get( Boy.class, boy.getId() ); assertNotNull( boy.getFavoriteToys() ); assertTrue( boy.getFavoriteToys().contains( toy ) ); + assertEquals( "@Parent is failing", boy, boy.getFavoriteToys().iterator().next().getOwner() ); s.delete( boy ); tx.commit(); s.close(); Modified: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/collectionelement/Toy.java =================================================================== --- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/collectionelement/Toy.java 2006-04-27 17:14:58 UTC (rev 9820) +++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/collectionelement/Toy.java 2006-04-27 21:12:40 UTC (rev 9821) @@ -5,6 +5,8 @@ import javax.persistence.Column; import javax.persistence.Embeddable; +import org.hibernate.annotations.Parent; + /** * @author Emmanuel Bernard */ @@ -13,6 +15,7 @@ private String name; private Brand brand; private String serial; + private Boy owner; @AttributeOverride(name = "name", column = @Column(name = "brand_name")) public Brand getBrand() { @@ -39,6 +42,15 @@ this.serial = serial; } + @Parent + public Boy getOwner() { + return owner; + } + + public void setOwner(Boy owner) { + this.owner = owner; + } + public boolean equals(Object o) { if ( this == o ) return true; if ( o == null || getClass() != o.getClass() ) return false; Modified: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/embedded/EmbeddedTest.java =================================================================== --- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/embedded/EmbeddedTest.java 2006-04-27 17:14:58 UTC (rev 9820) +++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/embedded/EmbeddedTest.java 2006-04-27 21:12:40 UTC (rev 9821) @@ -269,6 +269,31 @@ s.close(); } + public void testParent() throws Exception { + Session s; + s = openSession(); + s.getTransaction().begin(); + Book book = new Book(); + book.setIsbn( "1234" ); + book.setName( "HiA Second Edition" ); + Summary summary = new Summary(); + summary.setText( "This is a HiA SE summary" ); + summary.setSize( summary.getText().length() ); + book.setSummary( summary ); + s.persist( book ); + s.getTransaction().commit(); + + s.clear(); + + Transaction tx = s.beginTransaction(); + Book loadedBook = (Book) s.get( Book.class, book.getIsbn() ); + assertNotNull( loadedBook.getSummary() ); + assertEquals( loadedBook, loadedBook.getSummary().getSummarizedBook() ); + s.delete( loadedBook ); + tx.commit(); + s.close(); + } + public void testEmbeddedAndMultipleManyToOne() throws Exception { Session s; s = openSession(); Modified: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/embedded/Summary.java =================================================================== --- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/embedded/Summary.java 2006-04-27 17:14:58 UTC (rev 9820) +++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/embedded/Summary.java 2006-04-27 21:12:40 UTC (rev 9821) @@ -3,6 +3,8 @@ import javax.persistence.Embeddable; +import org.hibernate.annotations.Parent; + /** * @author Emmanuel Bernard */ @@ -10,6 +12,7 @@ public class Summary { private int size; private String text; + private Book summarizedBook; public int getSize() { return size; @@ -26,4 +29,13 @@ public void setText(String text) { this.text = text; } + + @Parent + public Book getSummarizedBook() { + return summarizedBook; + } + + public void setSummarizedBook(Book summarizedBook) { + this.summarizedBook = summarizedBook; + } } |