|
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;
+ }
}
|