Author: epbernard
Date: 2006-04-28 11:16:41 -0400 (Fri, 28 Apr 2006)
New Revision: 9830
Added:
trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/Fetch.java
trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/FetchMode.java
trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/LazyCollection.java
trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/LazyCollectionOption.java
trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/LazyToOne.java
trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/LazyToOneOption.java
Modified:
trunk/HibernateExt/metadata/doc/reference/en/modules/entity.xml
trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationBinder.java
trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/CollectionBinder.java
trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/fetch/FetchingTest.java
trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/fetch/Person.java
trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/fetch/Stay.java
Log:
ANN-224 @Fetch(FetchMode) @LazyToOne(LazyToOneOption) @LazyCollection(LazyCollectionOption)
Modified: trunk/HibernateExt/metadata/doc/reference/en/modules/entity.xml
===================================================================
--- trunk/HibernateExt/metadata/doc/reference/en/modules/entity.xml 2006-04-28 14:11:16 UTC (rev 9829)
+++ trunk/HibernateExt/metadata/doc/reference/en/modules/entity.xml 2006-04-28 15:16:41 UTC (rev 9830)
@@ -2556,6 +2556,106 @@
<para>In this case Hibernate generates a cascade delete constraint at
the database level.</para>
+
+ <sect3>
+ <title>Lazy options and fetching modes</title>
+
+ <para>EJB3 comes with the <literal>fetch</literal> option to define
+ lazy loading and fetching modes, however Hibernate has a much more
+ option set in this area. To fine tune the lazy loading and fetching
+ strategies, some additional annotations have been introduced: </para>
+
+ <itemizedlist>
+ <listitem>
+ <para><literal>@LazyToOne</literal>: defines the lazyness option
+ on <literal>@ManyToOne</literal> and <literal>@OneToOne</literal>
+ associations. <literal>LazyToOneOption</literal> can be
+ <literal>PROXY</literal> (ie use a proxy based lazy loading),
+ <literal>NO_PROXY</literal> (use a bytecode enhancement based lazy
+ loading - note that build time bytecode processing is necessary)
+ and <literal>FALSE</literal> (association not lazy)</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>@LazyCollection</literal>: defines the lazyness
+ option on <literal>@ManyTo</literal>Many and
+ <literal>@OneToMany</literal> associations. LazyCollectionOption
+ can be <literal>TRUE</literal> (the collection is lazy and will be
+ loaded when its state is accessed), <literal>EXTRA</literal> (the
+ collection is lazy and all operations will try to avoid the
+ collection loading, this is especially useful for huge collections
+ when loading all the elements is not necessary) and FALSE
+ (association not lazy)</para>
+ </listitem>
+
+ <listitem>
+ <para> <literal>@Fetch</literal>: defines the fetching strategy
+ used to load the association. <literal>FetchMode</literal> can be
+ <literal>SELECT</literal> (a select is triggered when the
+ association needs to be loaded), <literal>SUBSELECT</literal>
+ (only available for collections, use a subselect strategy - please
+ refers to the Hibernate Reference Documentation for more
+ information) or <literal>JOIN</literal> (use a SQL JOIN to load
+ the association while loading the owner entity).
+ <literal>JOIN</literal> overrides any lazy attribute (an
+ association loaded through a <literal>JOIN</literal> strategy
+ cannot be lazy).</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>The Hibernate annotations overrides the EJB3 fetching
+ options.</para>
+
+ <table>
+ <title>Lazy and fetch options equivalent</title>
+
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Annotations</entry>
+
+ <entry>Lazy</entry>
+
+ <entry>Fetch</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>@[One|Many]ToOne](fetch=FetchType.LAZY)</entry>
+
+ <entry>@LazyToOne(PROXY)</entry>
+
+ <entry>@Fetch(SELECT)</entry>
+ </row>
+
+ <row>
+ <entry>@[One|Many]ToOne](fetch=FetchType.EAGER)</entry>
+
+ <entry>@LazyToOne(FALSE)</entry>
+
+ <entry>@Fetch(JOIN)</entry>
+ </row>
+
+ <row>
+ <entry>@ManyTo[One|Many](fetch=FetchType.LAZY)</entry>
+
+ <entry>@LazyCollection(TRUE)</entry>
+
+ <entry>@Fetch(SELECT)</entry>
+ </row>
+
+ <row>
+ <entry>@ManyTo[One|Many](fetch=FetchType.EAGER)</entry>
+
+ <entry>@LazyCollection(FALSE)</entry>
+
+ <entry>@Fetch(JOIN)</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect3>
</sect2>
<sect2 id="entity-hibspec-collection" revision="2">
Added: trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/Fetch.java
===================================================================
--- trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/Fetch.java 2006-04-28 14:11:16 UTC (rev 9829)
+++ trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/Fetch.java 2006-04-28 15:16:41 UTC (rev 9830)
@@ -0,0 +1,18 @@
+//$Id: $
+package org.hibernate.annotations;
+
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Define the fetching strategy used for the given association
+ *
+ * @author Emmanuel Bernard
+ */
+@Target({ElementType.METHOD, ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Fetch {
+ FetchMode value();
+}
Added: trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/FetchMode.java
===================================================================
--- trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/FetchMode.java 2006-04-28 14:11:16 UTC (rev 9829)
+++ trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/FetchMode.java 2006-04-28 15:16:41 UTC (rev 9830)
@@ -0,0 +1,22 @@
+//$Id: $
+package org.hibernate.annotations;
+
+/**
+ * Fetch options on associations
+ *
+ * @author Emmanuel Bernard
+ */
+public enum FetchMode {
+ /**
+ * use a select for each individual entity, collection, or join load
+ */
+ SELECT,
+ /**
+ * use an outer join to load the related entities, collections or joins
+ */
+ JOIN,
+ /**
+ * use a subselect query to load the additional collections
+ */
+ SUBSELECT
+}
Added: trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/LazyCollection.java
===================================================================
--- trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/LazyCollection.java 2006-04-28 14:11:16 UTC (rev 9829)
+++ trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/LazyCollection.java 2006-04-28 15:16:41 UTC (rev 9830)
@@ -0,0 +1,18 @@
+//$Id: $
+package org.hibernate.annotations;
+
+import java.lang.annotation.Target;
+import java.lang.annotation.Retention;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Define the lazy status of a collection
+ *
+ * @author Emmanuel Bernard
+ */
+@Target({ElementType.METHOD, ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface LazyCollection {
+ LazyCollectionOption value();
+}
Added: trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/LazyCollectionOption.java
===================================================================
--- trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/LazyCollectionOption.java 2006-04-28 14:11:16 UTC (rev 9829)
+++ trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/LazyCollectionOption.java 2006-04-28 15:16:41 UTC (rev 9830)
@@ -0,0 +1,16 @@
+//$Id: $
+package org.hibernate.annotations;
+
+/**
+ * Lazy options available for a collection
+ *
+ * @author Emmanuel Bernard
+ */
+public enum LazyCollectionOption {
+ /** eagerly load it */
+ FALSE,
+ /** load it when the state is requested */
+ TRUE,
+ /** prefer extra queries over fill collection loading */
+ EXTRA
+}
Added: trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/LazyToOne.java
===================================================================
--- trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/LazyToOne.java 2006-04-28 14:11:16 UTC (rev 9829)
+++ trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/LazyToOne.java 2006-04-28 15:16:41 UTC (rev 9830)
@@ -0,0 +1,19 @@
+//$Id: $
+package org.hibernate.annotations;
+
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Define the lazy status of a ToOne association
+ * (ie OneToOne or ManyToOne)
+ *
+ * @author Emmanuel Bernard
+ */
+@Target({ElementType.METHOD, ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface LazyToOne {
+ LazyToOneOption value();
+}
Added: trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/LazyToOneOption.java
===================================================================
--- trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/LazyToOneOption.java 2006-04-28 14:11:16 UTC (rev 9829)
+++ trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/LazyToOneOption.java 2006-04-28 15:16:41 UTC (rev 9830)
@@ -0,0 +1,23 @@
+//$Id: $
+package org.hibernate.annotations;
+
+/**
+ * Lazy options available for a ToOne association
+ *
+ * @author Emmanuel Bernard
+ */
+public enum LazyToOneOption {
+ /** eagerly load the association */
+ FALSE,
+ /**
+ * Lazy, give back a proxy which will be loaded when the state is requested
+ * This should be the prefered option
+ */
+ PROXY,
+ /** Lazy, give back the real object loaded when a reference is requested
+ * (Bytecode enhancement is mandatory for this option, fall back to PROXY
+ * if the class is not enhanced)
+ * This option should be avoided unless you can't afford the use of proxies
+ */
+ NO_PROXY
+}
Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationBinder.java
===================================================================
--- trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationBinder.java 2006-04-28 14:11:16 UTC (rev 9829)
+++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationBinder.java 2006-04-28 15:16:41 UTC (rev 9830)
@@ -82,6 +82,9 @@
import org.hibernate.annotations.TypeDefs;
import org.hibernate.annotations.Where;
import org.hibernate.annotations.Parent;
+import org.hibernate.annotations.LazyToOne;
+import org.hibernate.annotations.Fetch;
+import org.hibernate.annotations.LazyToOneOption;
import org.hibernate.cfg.annotations.CollectionBinder;
import org.hibernate.cfg.annotations.EntityBinder;
import org.hibernate.cfg.annotations.Nullability;
@@ -108,6 +111,7 @@
import org.hibernate.mapping.Subclass;
import org.hibernate.mapping.Table;
import org.hibernate.mapping.UnionSubclass;
+import org.hibernate.mapping.ToOne;
import org.hibernate.persister.entity.JoinedSubclassEntityPersister;
import org.hibernate.persister.entity.SingleTableEntityPersister;
import org.hibernate.persister.entity.UnionSubclassEntityPersister;
@@ -1016,7 +1020,7 @@
);
}
- //set default values in needed
+ //set default values if needed
if ( joinColumns == null &&
( property.isAnnotationPresent( ManyToOne.class )
|| property.isAnnotationPresent( OneToOne.class ) )
@@ -1178,7 +1182,6 @@
getCascadeStrategy( ann.cascade(), hibernateCascade ),
joinColumns,
ann.optional(),
- getFetchMode( ann.fetch() ),
ignoreNotFound, onDeleteCascade,
mappings.getReflectionManager().toXClass( ann.targetEntity() ),
propertyHolder,
@@ -1662,7 +1665,7 @@
}
private static void bindManyToOne(
- String cascadeStrategy, Ejb3JoinColumn[] columns, boolean optional, FetchMode fetchMode,
+ String cascadeStrategy, Ejb3JoinColumn[] columns, boolean optional,
boolean ignoreNotFound, boolean cascadeOnDelete,
XClass targetEntity, PropertyHolder propertyHolder,
PropertyData inferredData, boolean unique, boolean isIdentifierMapper, ExtendedMappings mappings
@@ -1675,10 +1678,11 @@
else {
value.setReferencedEntityName( targetEntity.getName() );
}
- value.setFetchMode( fetchMode );
+ defineFetchingStrategy( value, inferredData.getProperty() );
+ //value.setFetchMode( fetchMode );
value.setIgnoreNotFound( ignoreNotFound );
value.setCascadeDeleteEnabled( cascadeOnDelete );
- value.setLazy( fetchMode != FetchMode.JOIN );
+ //value.setLazy( fetchMode != FetchMode.JOIN );
if ( !optional ) {
for ( Ejb3JoinColumn column : columns ) {
column.setNullable( false );
@@ -1717,6 +1721,50 @@
propertyHolder.addProperty( prop, columns );
}
+ private static void defineFetchingStrategy(ToOne toOne, XProperty property) {
+ LazyToOne lazy = property.getAnnotation( LazyToOne.class );
+ Fetch fetch = property.getAnnotation( Fetch.class );
+ ManyToOne manyToOne = property.getAnnotation( ManyToOne.class );
+ OneToOne oneToOne = property.getAnnotation( OneToOne.class );
+ FetchType fetchType;
+ if (manyToOne != null) {
+ fetchType = manyToOne.fetch();
+ }
+ else if (oneToOne != null) {
+ fetchType = oneToOne.fetch();
+ }
+ else {
+ throw new AssertionFailure( "Define fetch strategy on a property not annotated with @OneToMany nor @OneToOne");
+ }
+ if (lazy != null) {
+ toOne.setLazy( ! (lazy.value() == LazyToOneOption.FALSE) );
+ toOne.setUnwrapProxy( (lazy.value() == LazyToOneOption.NO_PROXY) );
+ }
+ else {
+ toOne.setLazy( fetchType == FetchType.LAZY );
+ toOne.setUnwrapProxy( false );
+ }
+ if (fetch != null) {
+ if ( fetch.value() == org.hibernate.annotations.FetchMode.JOIN ) {
+ toOne.setFetchMode( FetchMode.JOIN );
+ toOne.setLazy( false );
+ toOne.setUnwrapProxy( false );
+ }
+ else if ( fetch.value() == org.hibernate.annotations.FetchMode.SELECT ) {
+ toOne.setFetchMode( FetchMode.SELECT );
+ }
+ else if ( fetch.value() == org.hibernate.annotations.FetchMode.SUBSELECT ) {
+ throw new AnnotationException( "Use of FetchMode.SUBSELECT not allowed on ToOne associations");
+ }
+ else {
+ throw new AssertionFailure( "Unknown FetchMode: " + fetch.value() );
+ }
+ }
+ else {
+ toOne.setFetchMode( getFetchMode( fetchType ) );
+ }
+ }
+
private static void bindOneToOne(
String cascadeStrategy,
Ejb3JoinColumn[] columns,
@@ -1763,9 +1811,10 @@
else {
value.setReferencedEntityName( targetEntity.getName() );
}
- value.setFetchMode( fetchMode );
+ defineFetchingStrategy( value, inferredData.getProperty() );
+ //value.setFetchMode( fetchMode );
value.setCascadeDeleteEnabled( cascadeOnDelete );
- value.setLazy( fetchMode != FetchMode.JOIN );
+ //value.setLazy( fetchMode != FetchMode.JOIN );
if ( !optional ) value.setConstrained( true );
value.setForeignKeyType(
@@ -1809,7 +1858,7 @@
else {
//has a FK on the table
bindManyToOne(
- cascadeStrategy, columns, optional, fetchMode, ignoreNotFound, cascadeOnDelete,
+ cascadeStrategy, columns, optional, ignoreNotFound, cascadeOnDelete,
targetEntity,
propertyHolder, inferredData, true, isIdentifierMapper, mappings
);
@@ -1911,7 +1960,7 @@
return cascade.length() > 0 ? cascade.substring( 1 ) : "none";
}
- private static FetchMode getFetchMode(FetchType fetch) {
+ public static FetchMode getFetchMode(FetchType fetch) {
if ( fetch == FetchType.EAGER ) {
return FetchMode.JOIN;
}
Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/CollectionBinder.java
===================================================================
--- trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/CollectionBinder.java 2006-04-28 14:11:16 UTC (rev 9829)
+++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/CollectionBinder.java 2006-04-28 15:16:41 UTC (rev 9830)
@@ -11,7 +11,9 @@
import javax.persistence.AttributeOverrides;
import javax.persistence.Embeddable;
import javax.persistence.FetchType;
+import javax.persistence.ManyToMany;
import javax.persistence.MapKey;
+import javax.persistence.OneToMany;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -23,6 +25,9 @@
import org.hibernate.annotations.BatchSize;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CollectionOfElements;
+import org.hibernate.annotations.Fetch;
+import org.hibernate.annotations.LazyCollection;
+import org.hibernate.annotations.LazyCollectionOption;
import org.hibernate.annotations.OrderBy;
import org.hibernate.annotations.Sort;
import org.hibernate.annotations.SortType;
@@ -260,8 +265,9 @@
}
//set laziness
- collection.setFetchMode( fetchMode );
- collection.setLazy( fetchMode == FetchMode.SELECT );
+ defineFetchingStrategy();
+ //collection.setFetchMode( fetchMode );
+ //collection.setLazy( fetchMode == FetchMode.SELECT );
collection.setBatchSize( batchSize );
if ( orderBy != null && hqlOrderBy != null ) {
throw new AnnotationException(
@@ -371,6 +377,55 @@
propertyHolder.addProperty( prop );
}
+ private void defineFetchingStrategy() {
+ LazyCollection lazy = property.getAnnotation( LazyCollection.class );
+ Fetch fetch = property.getAnnotation( Fetch.class );
+ OneToMany oneToMany = property.getAnnotation( OneToMany.class );
+ ManyToMany manyToMany = property.getAnnotation( ManyToMany.class );
+ CollectionOfElements elements = property.getAnnotation( CollectionOfElements.class );
+ FetchType fetchType;
+ if (oneToMany != null) {
+ fetchType = oneToMany.fetch();
+ }
+ else if (manyToMany != null) {
+ fetchType = manyToMany.fetch();
+ }
+ else if (elements != null) {
+ fetchType = elements.fetch();
+ }
+ else {
+ throw new AssertionFailure( "Define fetch strategy on a property not annotated with @ManyToOne nor @OneToMany nor @CollectionOfElements");
+ }
+ if (lazy != null) {
+ collection.setLazy( ! (lazy.value() == LazyCollectionOption.FALSE) );
+ collection.setExtraLazy( lazy.value() == LazyCollectionOption.EXTRA );
+ }
+ else {
+ collection.setLazy( fetchType == FetchType.LAZY );
+ collection.setExtraLazy( false );
+ }
+ if (fetch != null) {
+ if ( fetch.value() == org.hibernate.annotations.FetchMode.JOIN ) {
+ collection.setFetchMode( FetchMode.JOIN );
+ collection.setLazy( false );
+ }
+ else if ( fetch.value() == org.hibernate.annotations.FetchMode.SELECT ) {
+ collection.setFetchMode( FetchMode.SELECT );
+ }
+ else if ( fetch.value() == org.hibernate.annotations.FetchMode.SUBSELECT ) {
+ collection.setFetchMode( FetchMode.SELECT );
+ collection.setSubselectLoadable(true);
+ collection.getOwner().setSubselectLoadableCollections(true);
+ }
+ else {
+ throw new AssertionFailure( "Unknown FetchMode: " + fetch.value() );
+ }
+ }
+ else {
+ collection.setFetchMode( AnnotationBinder.getFetchMode( fetchType ) );
+ }
+ }
+
private XClass getCollectionType() {
if ( AnnotationBinder.isDefault( targetEntity, mappings ) ) {
if ( collectionType != null ) {
Modified: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/fetch/FetchingTest.java
===================================================================
--- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/fetch/FetchingTest.java 2006-04-28 14:11:16 UTC (rev 9829)
+++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/fetch/FetchingTest.java 2006-04-28 15:16:41 UTC (rev 9830)
@@ -32,6 +32,41 @@
s.close();
}
+ public void testHibernateFetchingLazy() throws Exception {
+ Session s;
+ Transaction tx;
+ s = openSession();
+ tx = s.beginTransaction();
+ Person p = new Person( "Gavin", "King", "JBoss Inc" );
+ Stay stay = new Stay( null, new Date(), new Date(), "A380", "Blah", "Blah" );
+ Stay stay2 = new Stay( null, new Date(), new Date(), "A320", "Blah", "Blah" );
+ Stay stay3 = new Stay( null, new Date(), new Date(), "A340", "Blah", "Blah" );
+ stay.setOldPerson( p );
+ stay2.setVeryOldPerson( p );
+ stay3.setVeryOldPerson( p );
+ p.addOldStay( stay );
+ p.addVeryOldStay( stay2 );
+ p.addVeryOldStay( stay3 );
+ s.persist( p );
+ tx.commit();
+ s.clear();
+ tx = s.beginTransaction();
+ p = (Person) s.createQuery( "from Person p where p.firstName = :name" )
+ .setParameter( "name", "Gavin" ).uniqueResult();
+ assertFalse( Hibernate.isInitialized( p.getOldStays() ) );
+ assertEquals( 1, p.getOldStays().size() );
+ assertFalse( "lazy extra is failing", Hibernate.isInitialized( p.getOldStays() ) );
+ s.clear();
+ stay = (Stay) s.get( Stay.class, stay.getId() );
+ assertTrue( ! Hibernate.isInitialized( stay.getOldPerson() ) );
+ s.clear();
+ stay3 = (Stay) s.get( Stay.class, stay3.getId() );
+ assertTrue( "FetchMode.JOIN should overrides lazy options", Hibernate.isInitialized( stay3.getVeryOldPerson() ) );
+ s.delete( stay3.getVeryOldPerson() );
+ tx.commit();
+ s.close();
+ }
+
public FetchingTest(String x) {
super( x );
}
Modified: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/fetch/Person.java
===================================================================
--- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/fetch/Person.java 2006-04-28 14:11:16 UTC (rev 9829)
+++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/fetch/Person.java 2006-04-28 15:16:41 UTC (rev 9830)
@@ -14,7 +14,12 @@
import javax.persistence.OneToMany;
import javax.persistence.Table;
+import org.hibernate.annotations.Fetch;
+import org.hibernate.annotations.FetchMode;
+import org.hibernate.annotations.LazyCollection;
+import org.hibernate.annotations.LazyCollectionOption;
+
/**
* @author Emmanuel Bernard
*/
@@ -27,8 +32,9 @@
private String firstName;
private String lastName;
private String companyName;
-
private Collection<Stay> stays;
+ private Collection<Stay> oldStays;
+ private Collection<Stay> veryOldStays;
// constructors
public Person() {
@@ -86,7 +92,28 @@
this.stays = stays;
}
+ @OneToMany(cascade=CascadeType.ALL, mappedBy = "oldPerson")
+ @LazyCollection(LazyCollectionOption.EXTRA)
+ @Fetch(FetchMode.SUBSELECT)
+ public Collection<Stay> getOldStays() {
+ return oldStays;
+ }
+ public void setOldStays(Collection<Stay> oldStays) {
+ this.oldStays = oldStays;
+ }
+
+ @OneToMany(cascade=CascadeType.ALL, mappedBy = "veryOldPerson")
+ @Fetch(FetchMode.SELECT)
+ public Collection<Stay> getVeryOldStays() {
+ return veryOldStays;
+ }
+
+ public void setVeryOldStays(Collection<Stay> veryOldStays) {
+ this.veryOldStays = veryOldStays;
+ }
+
+
// business logic
public void addStay(Date startDate, Date endDate, String vessel, String authoriser, String comments) {
Stay stay = new Stay( this, startDate, endDate, vessel, authoriser, comments );
@@ -102,4 +129,34 @@
this.stays = stays;
}
+
+ public void addOldStay(Date startDate, Date endDate, String vessel, String authoriser, String comments) {
+ Stay stay = new Stay( this, startDate, endDate, vessel, authoriser, comments );
+ addOldStay( stay );
+ }
+
+ public void addOldStay(Stay stay) {
+ Collection<Stay> stays = getOldStays();
+ if ( stays == null ) {
+ stays = new ArrayList<Stay>();
+ }
+ stays.add( stay );
+
+ this.oldStays = stays;
+ }
+
+ public void addVeryOldStay(Date startDate, Date endDate, String vessel, String authoriser, String comments) {
+ Stay stay = new Stay( this, startDate, endDate, vessel, authoriser, comments );
+ addVeryOldStay( stay );
+ }
+
+ public void addVeryOldStay(Stay stay) {
+ Collection<Stay> stays = getVeryOldStays();
+ if ( stays == null ) {
+ stays = new ArrayList<Stay>();
+ }
+ stays.add( stay );
+
+ this.veryOldStays = stays;
+ }
}
Modified: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/fetch/Stay.java
===================================================================
--- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/fetch/Stay.java 2006-04-28 14:11:16 UTC (rev 9829)
+++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/fetch/Stay.java 2006-04-28 15:16:41 UTC (rev 9830)
@@ -12,6 +12,11 @@
import javax.persistence.ManyToOne;
import javax.persistence.Table;
+import org.hibernate.annotations.LazyToOne;
+import org.hibernate.annotations.LazyToOneOption;
+import org.hibernate.annotations.Fetch;
+import org.hibernate.annotations.FetchMode;
+
/**
* @author Emmanuel Bernard
*/
@@ -22,6 +27,8 @@
// member declaration
private int id;
private Person person;
+ private Person oldPerson;
+ private Person veryOldPerson;
private Date startDate;
private Date endDate;
private String vessel;
@@ -92,6 +99,30 @@
this.person = person;
}
+ @ManyToOne(cascade = CascadeType.ALL)
+ @LazyToOne(LazyToOneOption.PROXY)
+ @Fetch(FetchMode.SELECT)
+ @JoinColumn(name = "oldperson")
+ public Person getOldPerson() {
+ return oldPerson;
+ }
+
+ public void setOldPerson(Person oldPerson) {
+ this.oldPerson = oldPerson;
+ }
+
+ @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
+ @LazyToOne(LazyToOneOption.PROXY)
+ @Fetch(FetchMode.JOIN)
+ @JoinColumn(name = "veryoldperson")
+ public Person getVeryOldPerson() {
+ return veryOldPerson;
+ }
+
+ public void setVeryOldPerson(Person veryOldPerson) {
+ this.veryOldPerson = veryOldPerson;
+ }
+
public Date getStartDate() {
return startDate;
}
|