From 5fe0a801a0681cc4944187956a67b7b6d8936952 Mon Sep 17 00:00:00 2001 From: Gail Badner Date: Mon, 28 Jan 2008 22:18:35 +0000 Subject: [PATCH] HHH-2616 : collection recreate/remove/update events and listeners git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@14297 1b8cb986-b30d-0410-93ca-fae66ebed9b2 --- .../action/CollectionRecreateAction.java | 34 + .../action/CollectionRemoveAction.java | 100 ++- .../action/CollectionUpdateAction.java | 32 + .../java/org/hibernate/cfg/Configuration.java | 54 ++ .../hibernate/engine/PersistenceContext.java | 5 + .../engine/StatefulPersistenceContext.java | 11 + .../event/AbstractCollectionEvent.java | 58 ++ .../org/hibernate/event/EventListeners.java | 61 ++ .../event/InitializeCollectionEvent.java | 13 +- .../event/PostCollectionRecreateEvent.java | 16 + .../PostCollectionRecreateEventListener.java | 13 + .../event/PostCollectionRemoveEvent.java | 16 + .../PostCollectionRemoveEventListener.java | 13 + .../event/PostCollectionUpdateEvent.java | 16 + .../PostCollectionUpdateEventListener.java | 13 + .../event/PreCollectionRecreateEvent.java | 16 + .../PreCollectionRecreateEventListener.java | 13 + .../event/PreCollectionRemoveEvent.java | 40 + .../PreCollectionRemoveEventListener.java | 13 + .../event/PreCollectionUpdateEvent.java | 16 + .../PreCollectionUpdateEventListener.java | 12 + .../hibernate/event/def/ReattachVisitor.java | 2 +- .../AbstractCollectionEventTest.java | 761 ++++++++++++++++++ .../AbstractParentWithCollection.java | 100 +++ .../collection/BrokenCollectionEventTest.java | 322 ++++++++ .../test/event/collection/Child.java | 35 + .../test/event/collection/ChildEntity.java | 48 ++ .../test/event/collection/ChildValue.java | 63 ++ .../collection/CollectionEventSuite.java | 54 ++ .../event/collection/CollectionListeners.java | 214 +++++ .../collection/ParentWithCollection.java | 58 ++ ...bstractAssociationCollectionEventTest.java | 66 ++ ...ManyToManyBagToSetCollectionEventTest.java | 59 ++ ...rectionalManyToManyBagToSetMapping.hbm.xml | 35 + ...ManyToManySetToSetCollectionEventTest.java | 59 ++ ...rectionalManyToManySetToSetMapping.hbm.xml | 35 + .../ChildWithBidirectionalManyToMany.java | 66 ++ .../ParentWithBidirectionalManyToMany.java | 105 +++ ...tionalOneToManyBagCollectionEventTest.java | 65 ++ .../BidirectionalOneToManyBagMapping.hbm.xml | 32 + ...tionalOneToManySetCollectionEventTest.java | 65 ++ .../BidirectionalOneToManySetMapping.hbm.xml | 32 + .../onetomany/ChildWithManyToOne.java | 47 ++ .../ParentWithBidirectionalOneToMany.java | 85 ++ .../ParentWithCollectionOfEntities.java | 43 + ...ionalManyToManyBagCollectionEventTest.java | 65 ++ ...UnidirectionalManyToManyBagMapping.hbm.xml | 30 + ...tionalOneToManyBagCollectionEventTest.java | 65 ++ .../UnidirectionalOneToManyBagMapping.hbm.xml | 30 + ...tionalOneToManySetCollectionEventTest.java | 60 ++ .../UnidirectionalOneToManySetMapping.hbm.xml | 30 + .../values/ParentWithCollectionOfValues.java | 45 ++ .../values/ValuesBagCollectionEventTest.java | 59 ++ .../values/ValuesBagMapping.hbm.xml | 25 + 54 files changed, 3403 insertions(+), 22 deletions(-) create mode 100644 core/src/main/java/org/hibernate/event/AbstractCollectionEvent.java create mode 100644 core/src/main/java/org/hibernate/event/PostCollectionRecreateEvent.java create mode 100644 core/src/main/java/org/hibernate/event/PostCollectionRecreateEventListener.java create mode 100644 core/src/main/java/org/hibernate/event/PostCollectionRemoveEvent.java create mode 100644 core/src/main/java/org/hibernate/event/PostCollectionRemoveEventListener.java create mode 100644 core/src/main/java/org/hibernate/event/PostCollectionUpdateEvent.java create mode 100644 core/src/main/java/org/hibernate/event/PostCollectionUpdateEventListener.java create mode 100644 core/src/main/java/org/hibernate/event/PreCollectionRecreateEvent.java create mode 100644 core/src/main/java/org/hibernate/event/PreCollectionRecreateEventListener.java create mode 100644 core/src/main/java/org/hibernate/event/PreCollectionRemoveEvent.java create mode 100644 core/src/main/java/org/hibernate/event/PreCollectionRemoveEventListener.java create mode 100644 core/src/main/java/org/hibernate/event/PreCollectionUpdateEvent.java create mode 100644 core/src/main/java/org/hibernate/event/PreCollectionUpdateEventListener.java create mode 100644 testsuite/src/test/java/org/hibernate/test/event/collection/AbstractCollectionEventTest.java create mode 100644 testsuite/src/test/java/org/hibernate/test/event/collection/AbstractParentWithCollection.java create mode 100644 testsuite/src/test/java/org/hibernate/test/event/collection/BrokenCollectionEventTest.java create mode 100644 testsuite/src/test/java/org/hibernate/test/event/collection/Child.java create mode 100644 testsuite/src/test/java/org/hibernate/test/event/collection/ChildEntity.java create mode 100644 testsuite/src/test/java/org/hibernate/test/event/collection/ChildValue.java create mode 100644 testsuite/src/test/java/org/hibernate/test/event/collection/CollectionEventSuite.java create mode 100644 testsuite/src/test/java/org/hibernate/test/event/collection/CollectionListeners.java create mode 100644 testsuite/src/test/java/org/hibernate/test/event/collection/ParentWithCollection.java create mode 100644 testsuite/src/test/java/org/hibernate/test/event/collection/association/AbstractAssociationCollectionEventTest.java create mode 100644 testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/manytomany/BidirectionalManyToManyBagToSetCollectionEventTest.java create mode 100644 testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/manytomany/BidirectionalManyToManyBagToSetMapping.hbm.xml create mode 100644 testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/manytomany/BidirectionalManyToManySetToSetCollectionEventTest.java create mode 100644 testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/manytomany/BidirectionalManyToManySetToSetMapping.hbm.xml create mode 100644 testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/manytomany/ChildWithBidirectionalManyToMany.java create mode 100644 testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/manytomany/ParentWithBidirectionalManyToMany.java create mode 100644 testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/onetomany/BidirectionalOneToManyBagCollectionEventTest.java create mode 100644 testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/onetomany/BidirectionalOneToManyBagMapping.hbm.xml create mode 100644 testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/onetomany/BidirectionalOneToManySetCollectionEventTest.java create mode 100644 testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/onetomany/BidirectionalOneToManySetMapping.hbm.xml create mode 100644 testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/onetomany/ChildWithManyToOne.java create mode 100644 testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/onetomany/ParentWithBidirectionalOneToMany.java create mode 100644 testsuite/src/test/java/org/hibernate/test/event/collection/association/unidirectional/ParentWithCollectionOfEntities.java create mode 100644 testsuite/src/test/java/org/hibernate/test/event/collection/association/unidirectional/manytomany/UnidirectionalManyToManyBagCollectionEventTest.java create mode 100644 testsuite/src/test/java/org/hibernate/test/event/collection/association/unidirectional/manytomany/UnidirectionalManyToManyBagMapping.hbm.xml create mode 100644 testsuite/src/test/java/org/hibernate/test/event/collection/association/unidirectional/onetomany/UnidirectionalOneToManyBagCollectionEventTest.java create mode 100644 testsuite/src/test/java/org/hibernate/test/event/collection/association/unidirectional/onetomany/UnidirectionalOneToManyBagMapping.hbm.xml create mode 100644 testsuite/src/test/java/org/hibernate/test/event/collection/association/unidirectional/onetomany/UnidirectionalOneToManySetCollectionEventTest.java create mode 100644 testsuite/src/test/java/org/hibernate/test/event/collection/association/unidirectional/onetomany/UnidirectionalOneToManySetMapping.hbm.xml create mode 100644 testsuite/src/test/java/org/hibernate/test/event/collection/values/ParentWithCollectionOfValues.java create mode 100644 testsuite/src/test/java/org/hibernate/test/event/collection/values/ValuesBagCollectionEventTest.java create mode 100644 testsuite/src/test/java/org/hibernate/test/event/collection/values/ValuesBagMapping.hbm.xml diff --git a/core/src/main/java/org/hibernate/action/CollectionRecreateAction.java b/core/src/main/java/org/hibernate/action/CollectionRecreateAction.java index cdd05a2673..9d68e63839 100644 --- a/core/src/main/java/org/hibernate/action/CollectionRecreateAction.java +++ b/core/src/main/java/org/hibernate/action/CollectionRecreateAction.java @@ -2,6 +2,11 @@ package org.hibernate.action; import org.hibernate.HibernateException; +import org.hibernate.event.PostCollectionRecreateEventListener; +import org.hibernate.event.PostCollectionRecreateEvent; +import org.hibernate.event.EventSource; +import org.hibernate.event.PreCollectionRecreateEvent; +import org.hibernate.event.PreCollectionRecreateEventListener; import org.hibernate.cache.CacheException; import org.hibernate.collection.PersistentCollection; import org.hibernate.engine.SessionImplementor; @@ -21,8 +26,12 @@ public final class CollectionRecreateAction extends CollectionAction { } public void execute() throws HibernateException { + // this method is called when a new non-null collection is persisted + // or when an existing (non-null) collection is moved to a new owner final PersistentCollection collection = getCollection(); + preRecreate(); + getPersister().recreate( collection, getKey(), getSession() ); getSession().getPersistenceContext() @@ -31,12 +40,37 @@ public final class CollectionRecreateAction extends CollectionAction { evict(); + postRecreate(); + if ( getSession().getFactory().getStatistics().isStatisticsEnabled() ) { getSession().getFactory().getStatisticsImplementor() .recreateCollection( getPersister().getRole() ); } } + private void preRecreate() { + PreCollectionRecreateEventListener[] preListeners = getSession().getListeners() + .getPreCollectionRecreateEventListeners(); + if (preListeners.length > 0) { + PreCollectionRecreateEvent preEvent = new PreCollectionRecreateEvent( + getCollection(), ( EventSource ) getSession() ); + for ( int i = 0; i < preListeners.length; i++ ) { + preListeners[i].onPreRecreateCollection( preEvent ); + } + } + } + + private void postRecreate() { + PostCollectionRecreateEventListener[] postListeners = getSession().getListeners() + .getPostCollectionRecreateEventListeners(); + if (postListeners.length > 0) { + PostCollectionRecreateEvent postEvent = new PostCollectionRecreateEvent( + getCollection(), ( EventSource ) getSession() ); + for ( int i = 0; i < postListeners.length; i++ ) { + postListeners[i].onPostRecreateCollection( postEvent ); + } + } + } } diff --git a/core/src/main/java/org/hibernate/action/CollectionRemoveAction.java b/core/src/main/java/org/hibernate/action/CollectionRemoveAction.java index 2dcbf7a7a4..9fd521664a 100644 --- a/core/src/main/java/org/hibernate/action/CollectionRemoveAction.java +++ b/core/src/main/java/org/hibernate/action/CollectionRemoveAction.java @@ -2,6 +2,12 @@ package org.hibernate.action; import org.hibernate.HibernateException; +import org.hibernate.AssertionFailure; +import org.hibernate.event.PostCollectionRemoveEvent; +import org.hibernate.event.PreCollectionRemoveEvent; +import org.hibernate.event.PreCollectionRemoveEventListener; +import org.hibernate.event.EventSource; +import org.hibernate.event.PostCollectionRemoveEventListener; import org.hibernate.cache.CacheException; import org.hibernate.collection.PersistentCollection; import org.hibernate.engine.SessionImplementor; @@ -12,20 +18,71 @@ import java.io.Serializable; public final class CollectionRemoveAction extends CollectionAction { private boolean emptySnapshot; - + private final Object affectedOwner; + + /** + * Removes a persistent collection from its loaded owner. + * + * Use this constructor when the collection is non-null. + * + * @param collection The collection to to remove; must be non-null + * @param persister The collection's persister + * @param id The collection key + * @param emptySnapshot Indicates if the snapshot is empty + * @param session The session + * @throws AssertionFailure if collection is null. + */ public CollectionRemoveAction( final PersistentCollection collection, final CollectionPersister persister, - final Serializable id, - final boolean emptySnapshot, + final Serializable id, + final boolean emptySnapshot, final SessionImplementor session) throws CacheException { super( persister, collection, id, session ); + if (collection == null) { throw new AssertionFailure("collection == null"); } this.emptySnapshot = emptySnapshot; + // the loaded owner will be set to null after the collection is removed, + // so capture its value as the affected owner so it is accessible to + // both pre- and post- events + this.affectedOwner = session.getPersistenceContext().getLoadedCollectionOwner( collection ); } + /** + * Removes a persistent collection from a specified owner. + * + * Use this constructor when the collection to be removed has not been loaded. + * + * @param affectedOwner The collection's owner; must be non-null + * @param persister The collection's persister + * @param id The collection key + * @param emptySnapshot Indicates if the snapshot is empty + * @param session The session + * @throws AssertionFailure if affectedOwner is null. + */ + public CollectionRemoveAction( + final Object affectedOwner, + final CollectionPersister persister, + final Serializable id, + final boolean emptySnapshot, + final SessionImplementor session) + throws CacheException { + super( persister, null, id, session ); + if (affectedOwner == null) { throw new AssertionFailure("affectedOwner == null"); }; + this.emptySnapshot = emptySnapshot; + this.affectedOwner = affectedOwner; + } + public void execute() throws HibernateException { - if ( !emptySnapshot ) getPersister().remove( getKey(), getSession() ); + preRemove(); + + if ( !emptySnapshot ) { + // an existing collection that was either non-empty or uninitialized + // is replaced by null or a different collection + // (if the collection is uninitialized, hibernate has no way of + // knowing if the collection is actually empty without querying the db) + getPersister().remove( getKey(), getSession() ); + } final PersistentCollection collection = getCollection(); if (collection!=null) { @@ -36,18 +93,39 @@ public final class CollectionRemoveAction extends CollectionAction { evict(); + postRemove(); + if ( getSession().getFactory().getStatistics().isStatisticsEnabled() ) { getSession().getFactory().getStatisticsImplementor() .removeCollection( getPersister().getRole() ); } } + private void preRemove() { + PreCollectionRemoveEventListener[] preListeners = getSession().getListeners() + .getPreCollectionRemoveEventListeners(); + if (preListeners.length>0) { + PreCollectionRemoveEvent preEvent = new PreCollectionRemoveEvent( + getCollection(), + affectedOwner, + ( EventSource )getSession() ); + for ( int i = 0; i < preListeners.length; i++ ) { + preListeners[i].onPreRemoveCollection(preEvent); + } + } + } + private void postRemove() { + PostCollectionRemoveEventListener[] postListeners = getSession().getListeners() + .getPostCollectionRemoveEventListeners(); + if (postListeners.length>0) { + PostCollectionRemoveEvent postEvent = new PostCollectionRemoveEvent( + getCollection(), + affectedOwner, + ( EventSource )getSession() ); + for ( int i = 0; i < postListeners.length; i++ ) { + postListeners[i].onPostRemoveCollection(postEvent); + } + } + } } - - - - - - - diff --git a/core/src/main/java/org/hibernate/action/CollectionUpdateAction.java b/core/src/main/java/org/hibernate/action/CollectionUpdateAction.java index bfac0a89aa..d1f23ff595 100644 --- a/core/src/main/java/org/hibernate/action/CollectionUpdateAction.java +++ b/core/src/main/java/org/hibernate/action/CollectionUpdateAction.java @@ -3,6 +3,11 @@ package org.hibernate.action; import org.hibernate.AssertionFailure; import org.hibernate.HibernateException; +import org.hibernate.event.PostCollectionUpdateEvent; +import org.hibernate.event.PreCollectionUpdateEvent; +import org.hibernate.event.PreCollectionUpdateEventListener; +import org.hibernate.event.EventSource; +import org.hibernate.event.PostCollectionUpdateEventListener; import org.hibernate.cache.CacheException; import org.hibernate.collection.PersistentCollection; import org.hibernate.engine.SessionImplementor; @@ -33,6 +38,8 @@ public final class CollectionUpdateAction extends CollectionAction { final PersistentCollection collection = getCollection(); boolean affectedByFilters = persister.isAffectedByEnabledFilters(session); + preUpdate(); + if ( !collection.wasInitialized() ) { if ( !collection.hasQueuedOperations() ) throw new AssertionFailure( "no queued adds" ); //do nothing - we only need to notify the cache... @@ -62,12 +69,37 @@ public final class CollectionUpdateAction extends CollectionAction { evict(); + postUpdate(); + if ( getSession().getFactory().getStatistics().isStatisticsEnabled() ) { getSession().getFactory().getStatisticsImplementor(). updateCollection( getPersister().getRole() ); } } + + private void preUpdate() { + PreCollectionUpdateEventListener[] preListeners = getSession().getListeners() + .getPreCollectionUpdateEventListeners(); + if (preListeners.length > 0) { + PreCollectionUpdateEvent preEvent = new PreCollectionUpdateEvent( + getCollection(), ( EventSource ) getSession() ); + for ( int i = 0; i < preListeners.length; i++ ) { + preListeners[i].onPreUpdateCollection( preEvent ); + } + } + } + private void postUpdate() { + PostCollectionUpdateEventListener[] postListeners = getSession().getListeners() + .getPostCollectionUpdateEventListeners(); + if (postListeners.length > 0) { + PostCollectionUpdateEvent postEvent = new PostCollectionUpdateEvent( + getCollection(), ( EventSource ) getSession() ); + for ( int i = 0; i < postListeners.length; i++ ) { + postListeners[i].onPostUpdateCollection( postEvent ); + } + } + } } diff --git a/core/src/main/java/org/hibernate/cfg/Configuration.java b/core/src/main/java/org/hibernate/cfg/Configuration.java index 4f689790fe..c023489129 100644 --- a/core/src/main/java/org/hibernate/cfg/Configuration.java +++ b/core/src/main/java/org/hibernate/cfg/Configuration.java @@ -67,6 +67,12 @@ import org.hibernate.event.PreUpdateEventListener; import org.hibernate.event.RefreshEventListener; import org.hibernate.event.ReplicateEventListener; import org.hibernate.event.SaveOrUpdateEventListener; +import org.hibernate.event.PreCollectionRecreateEventListener; +import org.hibernate.event.PreCollectionRemoveEventListener; +import org.hibernate.event.PreCollectionUpdateEventListener; +import org.hibernate.event.PostCollectionUpdateEventListener; +import org.hibernate.event.PostCollectionRemoveEventListener; +import org.hibernate.event.PostCollectionRecreateEventListener; import org.hibernate.id.IdentifierGenerator; import org.hibernate.id.PersistentIdentifierGenerator; import org.hibernate.impl.SessionFactoryImpl; @@ -1863,6 +1869,30 @@ public class Configuration implements Serializable { eventListeners.setPreInsertEventListeners( (PreInsertEventListener[]) listeners ); } } + else if ( "pre-collection-recreate".equals( type ) ) { + if ( listeners == null ) { + eventListeners.setPreCollectionRecreateEventListeners( new PreCollectionRecreateEventListener[]{} ); + } + else { + eventListeners.setPreCollectionRecreateEventListeners( (PreCollectionRecreateEventListener[]) listeners ); + } + } + else if ( "pre-collection-remove".equals( type ) ) { + if ( listeners == null ) { + eventListeners.setPreCollectionRemoveEventListeners( new PreCollectionRemoveEventListener[]{} ); + } + else { + eventListeners.setPreCollectionRemoveEventListeners( ( PreCollectionRemoveEventListener[]) listeners ); + } + } + else if ( "pre-collection-update".equals( type ) ) { + if ( listeners == null ) { + eventListeners.setPreCollectionUpdateEventListeners( new PreCollectionUpdateEventListener[]{} ); + } + else { + eventListeners.setPreCollectionUpdateEventListeners( ( PreCollectionUpdateEventListener[]) listeners ); + } + } else if ( "post-load".equals( type ) ) { if ( listeners == null ) { eventListeners.setPostLoadEventListeners( new PostLoadEventListener[]{} ); @@ -1925,6 +1955,30 @@ public class Configuration implements Serializable { eventListeners.setPostCommitInsertEventListeners( (PostInsertEventListener[]) listeners ); } } + else if ( "post-collection-recreate".equals( type ) ) { + if ( listeners == null ) { + eventListeners.setPostCollectionRecreateEventListeners( new PostCollectionRecreateEventListener[]{} ); + } + else { + eventListeners.setPostCollectionRecreateEventListeners( (PostCollectionRecreateEventListener[]) listeners ); + } + } + else if ( "post-collection-remove".equals( type ) ) { + if ( listeners == null ) { + eventListeners.setPostCollectionRemoveEventListeners( new PostCollectionRemoveEventListener[]{} ); + } + else { + eventListeners.setPostCollectionRemoveEventListeners( ( PostCollectionRemoveEventListener[]) listeners ); + } + } + else if ( "post-collection-update".equals( type ) ) { + if ( listeners == null ) { + eventListeners.setPostCollectionUpdateEventListeners( new PostCollectionUpdateEventListener[]{} ); + } + else { + eventListeners.setPostCollectionUpdateEventListeners( ( PostCollectionUpdateEventListener[]) listeners ); + } + } else { throw new MappingException("Unrecognized listener type [" + type + "]"); } diff --git a/core/src/main/java/org/hibernate/engine/PersistenceContext.java b/core/src/main/java/org/hibernate/engine/PersistenceContext.java index e75f416b1b..bc1213b795 100644 --- a/core/src/main/java/org/hibernate/engine/PersistenceContext.java +++ b/core/src/main/java/org/hibernate/engine/PersistenceContext.java @@ -250,6 +250,11 @@ public interface PersistenceContext { public Object getCollectionOwner(Serializable key, CollectionPersister collectionPersister) throws MappingException; + /** + * Get the entity that owned this persistent collection when it was loaded + */ + Object getLoadedCollectionOwner(PersistentCollection collection); + /** * add a collection we just loaded up (still needs initializing) */ diff --git a/core/src/main/java/org/hibernate/engine/StatefulPersistenceContext.java b/core/src/main/java/org/hibernate/engine/StatefulPersistenceContext.java index a6ef4f95b4..c9d10be116 100644 --- a/core/src/main/java/org/hibernate/engine/StatefulPersistenceContext.java +++ b/core/src/main/java/org/hibernate/engine/StatefulPersistenceContext.java @@ -678,6 +678,17 @@ public class StatefulPersistenceContext implements PersistenceContext { return getEntity( new EntityKey( key, collectionPersister.getOwnerEntityPersister(), session.getEntityMode() ) ); } + /** + * Get the entity that owned this persistent collection when it was loaded + */ + public Object getLoadedCollectionOwner(PersistentCollection collection) { + CollectionEntry ce = getCollectionEntry(collection); + if ( ce.getLoadedKey() == null || ce.getLoadedPersister() == null ) { + return null; + } + return getCollectionOwner(ce.getLoadedKey(), ce.getLoadedPersister()); + } + /** * add a collection we just loaded up (still needs initializing) */ diff --git a/core/src/main/java/org/hibernate/event/AbstractCollectionEvent.java b/core/src/main/java/org/hibernate/event/AbstractCollectionEvent.java new file mode 100644 index 0000000000..fc25fd9573 --- /dev/null +++ b/core/src/main/java/org/hibernate/event/AbstractCollectionEvent.java @@ -0,0 +1,58 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Middleware LLC. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ + +//$Id: $ +package org.hibernate.event; + +import org.hibernate.collection.PersistentCollection; +import org.hibernate.engine.SessionImplementor; + +/** + * Defines a base class for events involving collections. + * + * @author Gail Badner + */ +public abstract class AbstractCollectionEvent extends AbstractEvent { + + private final PersistentCollection collection; + private final Object affectedOwner; + + public AbstractCollectionEvent(PersistentCollection collection, EventSource source, Object affectedOwner) { + super(source); + this.collection = collection; + this.affectedOwner = affectedOwner; + } + + protected static Object getLoadedOwner( PersistentCollection collection, EventSource source ) { + return ( ( SessionImplementor ) source ).getPersistenceContext().getLoadedCollectionOwner( collection ); + } + + public PersistentCollection getCollection() { + return collection; + } + + public Object getAffectedOwner() { + return affectedOwner; + } +} diff --git a/core/src/main/java/org/hibernate/event/EventListeners.java b/core/src/main/java/org/hibernate/event/EventListeners.java index c0be08ba7c..1bb6367363 100644 --- a/core/src/main/java/org/hibernate/event/EventListeners.java +++ b/core/src/main/java/org/hibernate/event/EventListeners.java @@ -69,6 +69,13 @@ public class EventListeners extends Cloneable implements Serializable { private PostUpdateEventListener[] postCommitUpdateEventListeners = {}; private PostInsertEventListener[] postCommitInsertEventListeners = {}; + private PreCollectionRecreateEventListener[] preCollectionRecreateEventListeners = {}; + private PostCollectionRecreateEventListener[] postCollectionRecreateEventListeners = {}; + private PreCollectionRemoveEventListener[] preCollectionRemoveEventListeners = {}; + private PostCollectionRemoveEventListener[] postCollectionRemoveEventListeners = {}; + private PreCollectionUpdateEventListener[] preCollectionUpdateEventListeners = {}; + private PostCollectionUpdateEventListener[] postCollectionUpdateEventListeners = {}; + private SaveOrUpdateEventListener[] saveEventListeners = { new DefaultSaveEventListener() }; private SaveOrUpdateEventListener[] updateEventListeners = { new DefaultUpdateEventListener() }; private MergeEventListener[] saveOrUpdateCopyEventListeners = { new DefaultSaveOrUpdateCopyEventListener() };//saveOrUpdateCopy() is deprecated! @@ -99,6 +106,9 @@ public class EventListeners extends Cloneable implements Serializable { eventInterfaceFromType.put("pre-update", PreUpdateEventListener.class); eventInterfaceFromType.put("pre-delete", PreDeleteEventListener.class); eventInterfaceFromType.put("pre-insert", PreInsertEventListener.class); + eventInterfaceFromType.put("pre-collection-recreate", PreCollectionRecreateEventListener.class); + eventInterfaceFromType.put("pre-collection-remove", PreCollectionRemoveEventListener.class); + eventInterfaceFromType.put("pre-collection-update", PreCollectionUpdateEventListener.class); eventInterfaceFromType.put("post-load", PostLoadEventListener.class); eventInterfaceFromType.put("post-update", PostUpdateEventListener.class); eventInterfaceFromType.put("post-delete", PostDeleteEventListener.class); @@ -106,6 +116,9 @@ public class EventListeners extends Cloneable implements Serializable { eventInterfaceFromType.put("post-commit-update", PostUpdateEventListener.class); eventInterfaceFromType.put("post-commit-delete", PostDeleteEventListener.class); eventInterfaceFromType.put("post-commit-insert", PostInsertEventListener.class); + eventInterfaceFromType.put("post-collection-recreate", PostCollectionRecreateEventListener.class); + eventInterfaceFromType.put("post-collection-remove", PostCollectionRemoveEventListener.class); + eventInterfaceFromType.put("post-collection-update", PostCollectionUpdateEventListener.class); eventInterfaceFromType = Collections.unmodifiableMap( eventInterfaceFromType ); } @@ -279,6 +292,30 @@ public class EventListeners extends Cloneable implements Serializable { this.preLoadEventListeners = preLoadEventListener; } + public PreCollectionRecreateEventListener[] getPreCollectionRecreateEventListeners() { + return preCollectionRecreateEventListeners; + } + + public void setPreCollectionRecreateEventListeners(PreCollectionRecreateEventListener[] preCollectionRecreateEventListener) { + this.preCollectionRecreateEventListeners = preCollectionRecreateEventListener; + } + + public PreCollectionRemoveEventListener[] getPreCollectionRemoveEventListeners() { + return preCollectionRemoveEventListeners; + } + + public void setPreCollectionRemoveEventListeners(PreCollectionRemoveEventListener[] preCollectionRemoveEventListener) { + this.preCollectionRemoveEventListeners = preCollectionRemoveEventListener; + } + + public PreCollectionUpdateEventListener[] getPreCollectionUpdateEventListeners() { + return preCollectionUpdateEventListeners; + } + + public void setPreCollectionUpdateEventListeners(PreCollectionUpdateEventListener[] preCollectionUpdateEventListeners) { + this.preCollectionUpdateEventListeners = preCollectionUpdateEventListeners; + } + public PostDeleteEventListener[] getPostDeleteEventListeners() { return postDeleteEventListeners; } @@ -303,6 +340,30 @@ public class EventListeners extends Cloneable implements Serializable { this.postUpdateEventListeners = postUpdateEventListener; } + public PostCollectionRecreateEventListener[] getPostCollectionRecreateEventListeners() { + return postCollectionRecreateEventListeners; + } + + public void setPostCollectionRecreateEventListeners(PostCollectionRecreateEventListener[] postCollectionRecreateEventListener) { + this.postCollectionRecreateEventListeners = postCollectionRecreateEventListener; + } + + public PostCollectionRemoveEventListener[] getPostCollectionRemoveEventListeners() { + return postCollectionRemoveEventListeners; + } + + public void setPostCollectionRemoveEventListeners(PostCollectionRemoveEventListener[] postCollectionRemoveEventListener) { + this.postCollectionRemoveEventListeners = postCollectionRemoveEventListener; + } + + public PostCollectionUpdateEventListener[] getPostCollectionUpdateEventListeners() { + return postCollectionUpdateEventListeners; + } + + public void setPostCollectionUpdateEventListeners(PostCollectionUpdateEventListener[] postCollectionUpdateEventListeners) { + this.postCollectionUpdateEventListeners = postCollectionUpdateEventListeners; + } + public PreDeleteEventListener[] getPreDeleteEventListeners() { return preDeleteEventListeners; } diff --git a/core/src/main/java/org/hibernate/event/InitializeCollectionEvent.java b/core/src/main/java/org/hibernate/event/InitializeCollectionEvent.java index 0a201e98be..fc99a076a0 100755 --- a/core/src/main/java/org/hibernate/event/InitializeCollectionEvent.java +++ b/core/src/main/java/org/hibernate/event/InitializeCollectionEvent.java @@ -9,16 +9,9 @@ import org.hibernate.collection.PersistentCollection; * * @author Gavin King */ -public class InitializeCollectionEvent extends AbstractEvent { - - private final PersistentCollection collection; +public class InitializeCollectionEvent extends AbstractCollectionEvent { public InitializeCollectionEvent(PersistentCollection collection, EventSource source) { - super(source); - this.collection = collection; - } - - public PersistentCollection getCollection() { - return collection; - } + super(collection, source, getLoadedOwner( collection, source ) ); + } } diff --git a/core/src/main/java/org/hibernate/event/PostCollectionRecreateEvent.java b/core/src/main/java/org/hibernate/event/PostCollectionRecreateEvent.java new file mode 100644 index 0000000000..4416591388 --- /dev/null +++ b/core/src/main/java/org/hibernate/event/PostCollectionRecreateEvent.java @@ -0,0 +1,16 @@ +//$Id: $ +package org.hibernate.event; + +import org.hibernate.collection.PersistentCollection; + +/** + * An event that occurs after a collection is recreated + * + * @author Gail Badner + */ +public class PostCollectionRecreateEvent extends AbstractCollectionEvent { + + public PostCollectionRecreateEvent(PersistentCollection collection, EventSource source) { + super(collection, source, collection.getOwner()); + } +} diff --git a/core/src/main/java/org/hibernate/event/PostCollectionRecreateEventListener.java b/core/src/main/java/org/hibernate/event/PostCollectionRecreateEventListener.java new file mode 100644 index 0000000000..7f6f90c2aa --- /dev/null +++ b/core/src/main/java/org/hibernate/event/PostCollectionRecreateEventListener.java @@ -0,0 +1,13 @@ +//$Id: $ +package org.hibernate.event; + +import java.io.Serializable; + +/** + * Called after recreating a collection + * + * @author Gail Badner + */ +public interface PostCollectionRecreateEventListener extends Serializable { + public void onPostRecreateCollection(PostCollectionRecreateEvent event); +} diff --git a/core/src/main/java/org/hibernate/event/PostCollectionRemoveEvent.java b/core/src/main/java/org/hibernate/event/PostCollectionRemoveEvent.java new file mode 100644 index 0000000000..72a9492b7c --- /dev/null +++ b/core/src/main/java/org/hibernate/event/PostCollectionRemoveEvent.java @@ -0,0 +1,16 @@ +//$Id: $ +package org.hibernate.event; + +import org.hibernate.collection.PersistentCollection; + +/** + * An event that occurs after a collection is removed + * + * @author Gail Badner + */ +public class PostCollectionRemoveEvent extends AbstractCollectionEvent { + + public PostCollectionRemoveEvent(PersistentCollection collection, Object loadedOwner, EventSource source) { + super(collection, source, loadedOwner); + } +} diff --git a/core/src/main/java/org/hibernate/event/PostCollectionRemoveEventListener.java b/core/src/main/java/org/hibernate/event/PostCollectionRemoveEventListener.java new file mode 100644 index 0000000000..6a77d46190 --- /dev/null +++ b/core/src/main/java/org/hibernate/event/PostCollectionRemoveEventListener.java @@ -0,0 +1,13 @@ +//$Id: $ +package org.hibernate.event; + +import java.io.Serializable; + +/** + * Called after removing a collection + * + * @author Gail Badner + */ +public interface PostCollectionRemoveEventListener extends Serializable { + public void onPostRemoveCollection(PostCollectionRemoveEvent event); +} diff --git a/core/src/main/java/org/hibernate/event/PostCollectionUpdateEvent.java b/core/src/main/java/org/hibernate/event/PostCollectionUpdateEvent.java new file mode 100644 index 0000000000..0bfee65303 --- /dev/null +++ b/core/src/main/java/org/hibernate/event/PostCollectionUpdateEvent.java @@ -0,0 +1,16 @@ +//$Id: $ +package org.hibernate.event; + +import org.hibernate.collection.PersistentCollection; + +/** + * An event that occurs after a collection is updated + * + * @author Gail Badner + */ +public class PostCollectionUpdateEvent extends AbstractCollectionEvent { + + public PostCollectionUpdateEvent(PersistentCollection collection, EventSource source) { + super(collection, source, getLoadedOwner( collection, source )); + } +} diff --git a/core/src/main/java/org/hibernate/event/PostCollectionUpdateEventListener.java b/core/src/main/java/org/hibernate/event/PostCollectionUpdateEventListener.java new file mode 100644 index 0000000000..c1686a04a7 --- /dev/null +++ b/core/src/main/java/org/hibernate/event/PostCollectionUpdateEventListener.java @@ -0,0 +1,13 @@ +//$Id: $ +package org.hibernate.event; + +import java.io.Serializable; + +/** + * Called after updating a collection + * + * @author Gail Badner + */ +public interface PostCollectionUpdateEventListener extends Serializable { + public void onPostUpdateCollection(PostCollectionUpdateEvent event); +} diff --git a/core/src/main/java/org/hibernate/event/PreCollectionRecreateEvent.java b/core/src/main/java/org/hibernate/event/PreCollectionRecreateEvent.java new file mode 100644 index 0000000000..73586c4947 --- /dev/null +++ b/core/src/main/java/org/hibernate/event/PreCollectionRecreateEvent.java @@ -0,0 +1,16 @@ +//$Id: $ +package org.hibernate.event; + +import org.hibernate.collection.PersistentCollection; + +/** + * An event that occurs before a collection is recreated + * + * @author Gail Badner + */ +public class PreCollectionRecreateEvent extends AbstractCollectionEvent { + + public PreCollectionRecreateEvent(PersistentCollection collection, EventSource source) { + super(collection, source, collection.getOwner()); + } +} diff --git a/core/src/main/java/org/hibernate/event/PreCollectionRecreateEventListener.java b/core/src/main/java/org/hibernate/event/PreCollectionRecreateEventListener.java new file mode 100644 index 0000000000..0690755961 --- /dev/null +++ b/core/src/main/java/org/hibernate/event/PreCollectionRecreateEventListener.java @@ -0,0 +1,13 @@ +//$Id: $ +package org.hibernate.event; + +import java.io.Serializable; + +/** + * Called before recreating a collection + * + * @author Gail Badner + */ +public interface PreCollectionRecreateEventListener extends Serializable { + public void onPreRecreateCollection(PreCollectionRecreateEvent event); +} diff --git a/core/src/main/java/org/hibernate/event/PreCollectionRemoveEvent.java b/core/src/main/java/org/hibernate/event/PreCollectionRemoveEvent.java new file mode 100644 index 0000000000..f242796964 --- /dev/null +++ b/core/src/main/java/org/hibernate/event/PreCollectionRemoveEvent.java @@ -0,0 +1,40 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Middleware LLC. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ + +//$Id: $ +package org.hibernate.event; + +import org.hibernate.collection.PersistentCollection; + +/** + * An event that occurs before a collection is removed + * + * @author Gail Badner + */ +public class PreCollectionRemoveEvent extends AbstractCollectionEvent { + + public PreCollectionRemoveEvent(PersistentCollection collection, Object loadedOwner, EventSource source) { + super(collection, source, loadedOwner); + } +} diff --git a/core/src/main/java/org/hibernate/event/PreCollectionRemoveEventListener.java b/core/src/main/java/org/hibernate/event/PreCollectionRemoveEventListener.java new file mode 100644 index 0000000000..5733c04f6c --- /dev/null +++ b/core/src/main/java/org/hibernate/event/PreCollectionRemoveEventListener.java @@ -0,0 +1,13 @@ +//$Id: $ +package org.hibernate.event; + +import java.io.Serializable; + +/** + * Called before removing a collection + * + * @author Gail Badner + */ +public interface PreCollectionRemoveEventListener extends Serializable { + public void onPreRemoveCollection(PreCollectionRemoveEvent event); +} diff --git a/core/src/main/java/org/hibernate/event/PreCollectionUpdateEvent.java b/core/src/main/java/org/hibernate/event/PreCollectionUpdateEvent.java new file mode 100644 index 0000000000..f226ed440f --- /dev/null +++ b/core/src/main/java/org/hibernate/event/PreCollectionUpdateEvent.java @@ -0,0 +1,16 @@ +//$Id: $ +package org.hibernate.event; + +import org.hibernate.collection.PersistentCollection; + +/** + * An event that occurs before a collection is updated + * + * @author Gail Badner + */ +public class PreCollectionUpdateEvent extends AbstractCollectionEvent { + + public PreCollectionUpdateEvent(PersistentCollection collection, EventSource source) { + super(collection, source, getLoadedOwner( collection, source )); + } +} diff --git a/core/src/main/java/org/hibernate/event/PreCollectionUpdateEventListener.java b/core/src/main/java/org/hibernate/event/PreCollectionUpdateEventListener.java new file mode 100644 index 0000000000..e8c1ede559 --- /dev/null +++ b/core/src/main/java/org/hibernate/event/PreCollectionUpdateEventListener.java @@ -0,0 +1,12 @@ +package org.hibernate.event; + +import java.io.Serializable; + +/** + * Called before updating a collection + * + * @author Gail Badner + */ +public interface PreCollectionUpdateEventListener extends Serializable { + public void onPreUpdateCollection(PreCollectionUpdateEvent event); +} diff --git a/core/src/main/java/org/hibernate/event/def/ReattachVisitor.java b/core/src/main/java/org/hibernate/event/def/ReattachVisitor.java index 072342710d..8d0b519ca8 100644 --- a/core/src/main/java/org/hibernate/event/def/ReattachVisitor.java +++ b/core/src/main/java/org/hibernate/event/def/ReattachVisitor.java @@ -79,7 +79,7 @@ public abstract class ReattachVisitor extends ProxyVisitor { MessageHelper.collectionInfoString( role, ownerIdentifier, source.getFactory() ) ); } - source.getActionQueue().addAction( new CollectionRemoveAction( null, role, collectionKey, false, source ) ); + source.getActionQueue().addAction( new CollectionRemoveAction( owner, role, collectionKey, false, source ) ); } /** diff --git a/testsuite/src/test/java/org/hibernate/test/event/collection/AbstractCollectionEventTest.java b/testsuite/src/test/java/org/hibernate/test/event/collection/AbstractCollectionEventTest.java new file mode 100644 index 0000000000..18fd810fbb --- /dev/null +++ b/testsuite/src/test/java/org/hibernate/test/event/collection/AbstractCollectionEventTest.java @@ -0,0 +1,761 @@ +//$Id: $ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2007, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution statements + * applied by the authors. + * + * All third-party contributions are distributed under license by Red Hat + * Middleware LLC. This copyrighted material is made available to anyone + * wishing to use, modify, copy, or redistribute it subject to the terms + * and conditions of the GNU Lesser General Public License, as published by + * the Free Software Foundation. This program is distributed in the hope + * that it will be useful, but WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU Lesser General Public License for more details. You should + * have received a copy of the GNU Lesser General Public License along with + * this distribution; if not, write to: Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor Boston, MA 02110-1301 USA + */ +package org.hibernate.test.event.collection; + +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import org.hibernate.Session; +import org.hibernate.Transaction; +import org.hibernate.collection.PersistentCollection; +import org.hibernate.collection.PersistentSet; +import org.hibernate.event.AbstractCollectionEvent; +import org.hibernate.junit.functional.FunctionalTestCase; +import org.hibernate.test.event.collection.association.bidirectional.manytomany.ChildWithBidirectionalManyToMany; + +/** + * + * @author Gail Badner + */ +public abstract class AbstractCollectionEventTest extends FunctionalTestCase { + + public AbstractCollectionEventTest(String string) { + super( string ); + } + + public abstract String[] getMappings(); + + public abstract ParentWithCollection createParent(String name); + + public abstract Collection createCollection(); + + protected void cleanupTest() { + ParentWithCollection dummyParent = createParent( "dummyParent" ); + dummyParent.newChildren( createCollection() ); + Child dummyChild = dummyParent.addChild( "dummyChild" ); + Session s = openSession(); + Transaction tx = s.beginTransaction(); + List children = s.createCriteria( dummyChild.getClass() ).list(); + List parents = s.createCriteria( dummyParent.getClass() ).list(); + for ( Iterator it = parents.iterator(); it.hasNext(); ) { + ParentWithCollection parent = ( ParentWithCollection ) it.next(); + parent.clearChildren(); + s.delete( parent ); + } + for ( Iterator it = children.iterator(); it.hasNext(); ) { + s.delete( it.next() ); + } + tx.commit(); + s.close(); + } + + public void testSaveParentEmptyChildren() { + CollectionListeners listeners = new CollectionListeners( getSessions() ); + ParentWithCollection parent = createParentWithNoChildren( "parent" ); + assertEquals( 0, parent.getChildren().size() ); + int index = 0; + checkResult( listeners, listeners.getPreCollectionRecreateListener(), parent, index++ ); + checkResult( listeners, listeners.getPostCollectionRecreateListener(), parent, index++ ); + checkNumberOfResults( listeners, index ); + listeners.clear(); + Session s = openSession(); + Transaction tx = s.beginTransaction(); + parent = ( ParentWithCollection ) s.get( parent.getClass(), parent.getId() ); + tx.commit(); + s.close(); + assertNotNull( parent.getChildren() ); + checkNumberOfResults( listeners, 0 ); + } + + public void testSaveParentOneChild() { + CollectionListeners listeners = new CollectionListeners( getSessions() ); + ParentWithCollection parent = createParentWithOneChild( "parent", "child" ); + int index = 0; + checkResult( listeners, listeners.getPreCollectionRecreateListener(), parent, index++ ); + checkResult( listeners, listeners.getPostCollectionRecreateListener(), parent, index++ ); + Child child = ( Child ) parent.getChildren().iterator().next(); + if ( child.hasBidirectionalManyToMany() ) { + checkResult( listeners, listeners.getPreCollectionRecreateListener(), child, index++ ); + checkResult( listeners, listeners.getPostCollectionRecreateListener(), child, index++ ); + } + checkNumberOfResults( listeners, index ); + } + + public void testUpdateParentNullToOneChild() { + CollectionListeners listeners = new CollectionListeners( getSessions() ); + ParentWithCollection parent = createParentWithNullChildren( "parent" ); + listeners.clear(); + assertNull( parent.getChildren() ); + Session s = openSession(); + Transaction tx = s.beginTransaction(); + parent = ( ParentWithCollection ) s.get( parent.getClass(), parent.getId() ); + assertNotNull( parent.getChildren() ); + Child newChild = parent.addChild( "new" ); + tx.commit(); + s.close(); + int index = 0; + if ( ( ( PersistentCollection ) parent.getChildren() ).wasInitialized() ) { + checkResult( listeners, listeners.getInitializeCollectionListener(), parent, index++ ); + } + checkResult( listeners, listeners.getPreCollectionUpdateListener(), parent, index++ ); + checkResult( listeners, listeners.getPostCollectionUpdateListener(), parent, index++ ); + if ( newChild.hasBidirectionalManyToMany() ) { + checkResult( listeners, listeners.getPreCollectionRecreateListener(), newChild, index++ ); + checkResult( listeners, listeners.getPostCollectionRecreateListener(), newChild, index++ ); + } + checkNumberOfResults( listeners, index ); + } + + public void testUpdateParentNoneToOneChild() { + CollectionListeners listeners = new CollectionListeners( getSessions() ); + ParentWithCollection parent = createParentWithNoChildren( "parent" ); + listeners.clear(); + assertEquals( 0, parent.getChildren().size() ); + Session s = openSession(); + Transaction tx = s.beginTransaction(); + parent = ( ParentWithCollection ) s.get( parent.getClass(), parent.getId() ); + Child newChild = parent.addChild( "new" ); + tx.commit(); + s.close(); + int index = 0; + if ( ( ( PersistentCollection ) parent.getChildren() ).wasInitialized() ) { + checkResult( listeners, listeners.getInitializeCollectionListener(), parent, index++ ); + } + checkResult( listeners, listeners.getPreCollectionUpdateListener(), parent, index++ ); + checkResult( listeners, listeners.getPostCollectionUpdateListener(), parent, index++ ); + if ( newChild.hasBidirectionalManyToMany() ) { + checkResult( listeners, listeners.getPreCollectionRecreateListener(), newChild, index++ ); + checkResult( listeners, listeners.getPostCollectionRecreateListener(), newChild, index++ ); + } + checkNumberOfResults( listeners, index ); + } + + public void testUpdateParentOneToTwoChildren() { + CollectionListeners listeners = new CollectionListeners( getSessions() ); + ParentWithCollection parent = createParentWithOneChild( "parent", "child" ); + assertEquals( 1, parent.getChildren().size() ); + listeners.clear(); + Session s = openSession(); + Transaction tx = s.beginTransaction(); + parent = ( ParentWithCollection ) s.get( parent.getClass(), parent.getId() ); + Child newChild = parent.addChild( "new2" ); + tx.commit(); + s.close(); + int index = 0; + if ( ( ( PersistentCollection ) parent.getChildren() ).wasInitialized() ) { + checkResult( listeners, listeners.getInitializeCollectionListener(), parent, index++ ); + } + checkResult( listeners, listeners.getPreCollectionUpdateListener(), parent, index++ ); + checkResult( listeners, listeners.getPostCollectionUpdateListener(), parent, index++ ); + if ( newChild.hasBidirectionalManyToMany() ) { + checkResult( listeners, listeners.getPreCollectionRecreateListener(), newChild, index++ ); + checkResult( listeners, listeners.getPostCollectionRecreateListener(), newChild, index++ ); + } + checkNumberOfResults( listeners, index ); + } + + public void testUpdateParentOneToTwoSameChildren() { + CollectionListeners listeners = new CollectionListeners( getSessions() ); + ParentWithCollection parent = createParentWithOneChild( "parent", "child" ); + Child child = ( Child ) parent.getChildren().iterator().next(); + assertEquals( 1, parent.getChildren().size() ); + listeners.clear(); + Session s = openSession(); + Transaction tx = s.beginTransaction(); + parent = ( ParentWithCollection ) s.get( parent.getClass(), parent.getId() ); + if ( child instanceof ChildEntity ) { + child = ( Child ) s.get( child.getClass(), ( ( ChildEntity ) child ).getId() ); + } + parent.addChild( child ); + tx.commit(); + s.close(); + int index = 0; + if ( ( ( PersistentCollection ) parent.getChildren() ).wasInitialized() ) { + checkResult( listeners, listeners.getInitializeCollectionListener(), parent, index++ ); + } + if ( child.hasBidirectionalManyToMany() && ( ( PersistentCollection ) getParents( child ) ).wasInitialized() ) { + checkResult( listeners, listeners.getInitializeCollectionListener(), child, index++ ); + } + if ( !( parent.getChildren() instanceof PersistentSet ) ) { + checkResult( listeners, listeners.getPreCollectionUpdateListener(), parent, index++ ); + checkResult( listeners, listeners.getPostCollectionUpdateListener(), parent, index++ ); + } + if ( child.hasBidirectionalManyToMany() && !( getParents( child ) instanceof PersistentSet ) ) { + checkResult( listeners, listeners.getPreCollectionUpdateListener(), child, index++ ); + checkResult( listeners, listeners.getPostCollectionUpdateListener(), child, index++ ); + } + checkNumberOfResults( listeners, index ); + } + + public void testUpdateParentNullToOneChildDiffCollection() { + CollectionListeners listeners = new CollectionListeners( getSessions() ); + ParentWithCollection parent = createParentWithNullChildren( "parent" ); + listeners.clear(); + assertNull( parent.getChildren() ); + Session s = openSession(); + Transaction tx = s.beginTransaction(); + parent = ( ParentWithCollection ) s.get( parent.getClass(), parent.getId() ); + Collection collectionOrig = parent.getChildren(); + parent.newChildren( createCollection() ); + Child newChild = parent.addChild( "new" ); + tx.commit(); + s.close(); + int index = 0; + if ( ( ( PersistentCollection ) collectionOrig ).wasInitialized() ) { + checkResult( listeners, listeners.getInitializeCollectionListener(), parent, collectionOrig, index++ ); + } + checkResult( listeners, listeners.getPreCollectionRemoveListener(), parent, collectionOrig, index++ ); + checkResult( listeners, listeners.getPostCollectionRemoveListener(), parent, collectionOrig, index++ ); + if ( newChild.hasBidirectionalManyToMany() ) { + checkResult( listeners, listeners.getPreCollectionRecreateListener(), newChild, index++ ); + checkResult( listeners, listeners.getPostCollectionRecreateListener(), newChild, index++ ); + } + checkResult( listeners, listeners.getPreCollectionRecreateListener(), parent, index++ ); + checkResult( listeners, listeners.getPostCollectionRecreateListener(), parent, index++ ); + checkNumberOfResults( listeners, index ); + } + + public void testUpdateParentNoneToOneChildDiffCollection() { + CollectionListeners listeners = new CollectionListeners( getSessions() ); + ParentWithCollection parent = createParentWithNoChildren( "parent" ); + listeners.clear(); + assertEquals( 0, parent.getChildren().size() ); + Session s = openSession(); + Transaction tx = s.beginTransaction(); + parent = ( ParentWithCollection ) s.get( parent.getClass(), parent.getId() ); + Collection oldCollection = parent.getChildren(); + parent.newChildren( createCollection() ); + Child newChild = parent.addChild( "new" ); + tx.commit(); + s.close(); + int index = 0; + if ( ( ( PersistentCollection ) oldCollection ).wasInitialized() ) { + checkResult( listeners, listeners.getInitializeCollectionListener(), parent, oldCollection, index++ ); + } + checkResult( listeners, listeners.getPreCollectionRemoveListener(), parent, oldCollection, index++ ); + checkResult( listeners, listeners.getPostCollectionRemoveListener(), parent, oldCollection, index++ ); + if ( newChild.hasBidirectionalManyToMany() ) { + checkResult( listeners, listeners.getPreCollectionRecreateListener(), newChild, index++ ); + checkResult( listeners, listeners.getPostCollectionRecreateListener(), newChild, index++ ); + } + checkResult( listeners, listeners.getPreCollectionRecreateListener(), parent, index++ ); + checkResult( listeners, listeners.getPostCollectionRecreateListener(), parent, index++ ); + checkNumberOfResults( listeners, index ); + } + + public void testUpdateParentOneChildDiffCollectionSameChild() { + CollectionListeners listeners = new CollectionListeners( getSessions() ); + ParentWithCollection parent = createParentWithOneChild( "parent", "child" ); + Child child = ( Child ) parent.getChildren().iterator().next(); + listeners.clear(); + assertEquals( 1, parent.getChildren().size() ); + Session s = openSession(); + Transaction tx = s.beginTransaction(); + parent = ( ParentWithCollection ) s.get( parent.getClass(), parent.getId() ); + if ( child instanceof ChildEntity ) { + child = ( ChildEntity ) s.get( child.getClass(), ( ( ChildEntity ) child).getId() ); + } + Collection oldCollection = parent.getChildren(); + parent.newChildren( createCollection() ); + parent.addChild( child ); + tx.commit(); + s.close(); + int index = 0; + if ( ( ( PersistentCollection ) oldCollection ).wasInitialized() ) { + checkResult( listeners, listeners.getInitializeCollectionListener(), parent, oldCollection, index++ ); + } + if ( child.hasBidirectionalManyToMany() && ( ( PersistentCollection ) getParents( child ) ).wasInitialized() ) { + checkResult( listeners, listeners.getInitializeCollectionListener(), child, index++ ); + } + checkResult( listeners, listeners.getPreCollectionRemoveListener(), parent, oldCollection, index++ ); + checkResult( listeners, listeners.getPostCollectionRemoveListener(), parent, oldCollection, index++ ); + if ( child.hasBidirectionalManyToMany() ) { + // hmmm, the same parent was removed and re-added to the child's collection; + // should this be considered an update? + checkResult( listeners, listeners.getPreCollectionUpdateListener(), child, index++ ); + checkResult( listeners, listeners.getPostCollectionUpdateListener(), child, index++ ); + } + checkResult( listeners, listeners.getPreCollectionRecreateListener(), parent, index++ ); + checkResult( listeners, listeners.getPostCollectionRecreateListener(), parent, index++ ); + checkNumberOfResults( listeners, index ); + } + + public void testUpdateParentOneChildDiffCollectionDiffChild() { + CollectionListeners listeners = new CollectionListeners( getSessions() ); + ParentWithCollection parent = createParentWithOneChild( "parent", "child" ); + Child oldChild = ( Child ) parent.getChildren().iterator().next(); + listeners.clear(); + assertEquals( 1, parent.getChildren().size() ); + Session s = openSession(); + Transaction tx = s.beginTransaction(); + parent = ( ParentWithCollection ) s.get( parent.getClass(), parent.getId() ); + if ( oldChild instanceof ChildEntity ) { + oldChild = ( ChildEntity ) s.get( oldChild.getClass(), ( ( ChildEntity ) oldChild).getId() ); + } + Collection oldCollection = parent.getChildren(); + parent.newChildren( createCollection() ); + Child newChild = parent.addChild( "new1" ); + tx.commit(); + s.close(); + int index = 0; + if ( ( ( PersistentCollection ) oldCollection ).wasInitialized() ) { + checkResult( listeners, listeners.getInitializeCollectionListener(), parent, oldCollection, index++ ); + } + if ( oldChild.hasBidirectionalManyToMany() && ( ( PersistentCollection ) getParents( oldChild ) ).wasInitialized() ) { + checkResult( listeners, listeners.getInitializeCollectionListener(), oldChild, index++ ); + } + checkResult( listeners, listeners.getPreCollectionRemoveListener(), parent, oldCollection, index++ ); + checkResult( listeners, listeners.getPostCollectionRemoveListener(), parent, oldCollection, index++ ); + if ( oldChild.hasBidirectionalManyToMany() ) { + checkResult( listeners, listeners.getPreCollectionUpdateListener(), oldChild, index++ ); + checkResult( listeners, listeners.getPostCollectionUpdateListener(), oldChild, index++ ); + checkResult( listeners, listeners.getPreCollectionRecreateListener(), newChild, index++ ); + checkResult( listeners, listeners.getPostCollectionRecreateListener(), newChild, index++ ); + } + checkResult( listeners, listeners.getPreCollectionRecreateListener(), parent, index++ ); + checkResult( listeners, listeners.getPostCollectionRecreateListener(), parent, index++ ); + checkNumberOfResults( listeners, index ); + } + + public void testUpdateParentOneChildToNoneByRemove() { + CollectionListeners listeners = new CollectionListeners( getSessions() ); + ParentWithCollection parent = createParentWithOneChild( "parent", "child" ); + assertEquals( 1, parent.getChildren().size() ); + Child child = ( Child ) parent.getChildren().iterator().next(); + listeners.clear(); + Session s = openSession(); + Transaction tx = s.beginTransaction(); + parent = ( ParentWithCollection ) s.get( parent.getClass(), parent.getId() ); + if ( child instanceof ChildEntity ) { + child = ( Child ) s.get( child.getClass(), ( ( ChildEntity ) child ).getId() ); + } + parent.removeChild( child ); + tx.commit(); + s.close(); + int index = 0; + if ( ( ( PersistentCollection ) parent.getChildren() ).wasInitialized() ) { + checkResult( listeners, listeners.getInitializeCollectionListener(), parent, index++ ); + } + if ( child.hasBidirectionalManyToMany() && ( ( PersistentCollection ) getParents( child ) ).wasInitialized() ) { + checkResult( listeners, listeners.getInitializeCollectionListener(), child, index++ ); + } + checkResult( listeners, listeners.getPreCollectionUpdateListener(), parent, index++ ); + checkResult( listeners, listeners.getPostCollectionUpdateListener(), parent, index++ ); + if ( child.hasBidirectionalManyToMany() ) { + checkResult( listeners, listeners.getPreCollectionUpdateListener(), child, index++ ); + checkResult( listeners, listeners.getPostCollectionUpdateListener(), child, index++ ); + } + checkNumberOfResults( listeners, index ); + } + + public void testUpdateParentOneChildToNoneByClear() { + CollectionListeners listeners = new CollectionListeners( getSessions() ); + ParentWithCollection parent = createParentWithOneChild( "parent", "child" ); + assertEquals( 1, parent.getChildren().size() ); + Child child = ( Child ) parent.getChildren().iterator().next(); + listeners.clear(); + Session s = openSession(); + Transaction tx = s.beginTransaction(); + parent = ( ParentWithCollection ) s.get( parent.getClass(), parent.getId() ); + if ( child instanceof ChildEntity ) { + child = ( Child ) s.get( child.getClass(), ( ( ChildEntity ) child ).getId() ); + } + parent.clearChildren(); + tx.commit(); + s.close(); + int index = 0; + if ( ( ( PersistentCollection ) parent.getChildren() ).wasInitialized() ) { + checkResult( listeners, listeners.getInitializeCollectionListener(), parent, index++ ); + } + if ( child.hasBidirectionalManyToMany() && ( ( PersistentCollection ) getParents( child ) ).wasInitialized() ) { + checkResult( listeners, listeners.getInitializeCollectionListener(), child, index++ ); + } + checkResult( listeners, listeners.getPreCollectionUpdateListener(), parent, index++ ); + checkResult( listeners, listeners.getPostCollectionUpdateListener(), parent, index++ ); + if ( child.hasBidirectionalManyToMany() ) { + checkResult( listeners, listeners.getPreCollectionUpdateListener(), child, index++ ); + checkResult( listeners, listeners.getPostCollectionUpdateListener(), child, index++ ); + } + checkNumberOfResults( listeners, index ); + } + + public void testUpdateParentTwoChildrenToOne() { + CollectionListeners listeners = new CollectionListeners( getSessions() ); + ParentWithCollection parent = createParentWithOneChild( "parent", "child" ); + assertEquals( 1, parent.getChildren().size() ); + Child oldChild = ( Child ) parent.getChildren().iterator().next(); + listeners.clear(); + Session s = openSession(); + Transaction tx = s.beginTransaction(); + parent = ( ParentWithCollection ) s.get( parent.getClass(), parent.getId() ); + parent.addChild( "new" ); + tx.commit(); + s.close(); + listeners.clear(); + s = openSession(); + tx = s.beginTransaction(); + parent = ( ParentWithCollection ) s.get( parent.getClass(), parent.getId() ); + if ( oldChild instanceof ChildEntity ) { + oldChild = ( Child ) s.get( oldChild.getClass(), ( ( ChildEntity ) oldChild ).getId() ); + } + parent.removeChild( oldChild ); + tx.commit(); + s.close(); + int index = 0; + if ( ( ( PersistentCollection ) parent.getChildren() ).wasInitialized() ) { + checkResult( listeners, listeners.getInitializeCollectionListener(), parent, index++ ); + } + if ( oldChild.hasBidirectionalManyToMany() && ( ( PersistentCollection ) getParents( oldChild ) ).wasInitialized() ) { + checkResult( listeners, listeners.getInitializeCollectionListener(), oldChild, index++ ); + } + checkResult( listeners, listeners.getPreCollectionUpdateListener(), parent, index++ ); + checkResult( listeners, listeners.getPostCollectionUpdateListener(), parent, index++ ); + if ( oldChild.hasBidirectionalManyToMany() ) { + checkResult( listeners, listeners.getPreCollectionUpdateListener(), oldChild, index++ ); + checkResult( listeners, listeners.getPostCollectionUpdateListener(), oldChild, index++ ); + } + checkNumberOfResults( listeners, index ); + } + + public void testDeleteParentWithNullChildren() { + CollectionListeners listeners = new CollectionListeners( getSessions() ); + ParentWithCollection parent = createParentWithNullChildren( "parent" ); + listeners.clear(); + Session s = openSession(); + Transaction tx = s.beginTransaction(); + parent = ( ParentWithCollection ) s.get( parent.getClass(), parent.getId() ); + s.delete( parent ); + tx.commit(); + s.close(); + int index = 0; + checkResult( listeners, listeners.getInitializeCollectionListener(), parent, index++ ); + checkResult( listeners, listeners.getPreCollectionRemoveListener(), parent, index++ ); + checkResult( listeners, listeners.getPostCollectionRemoveListener(), parent, index++ ); + checkNumberOfResults( listeners, index ); + } + + public void testDeleteParentWithNoChildren() { + CollectionListeners listeners = new CollectionListeners( getSessions() ); + ParentWithCollection parent = createParentWithNoChildren( "parent" ); + listeners.clear(); + Session s = openSession(); + Transaction tx = s.beginTransaction(); + parent = ( ParentWithCollection ) s.get( parent.getClass(), parent.getId() ); + s.delete( parent ); + tx.commit(); + s.close(); + int index = 0; + checkResult( listeners, listeners.getInitializeCollectionListener(), parent, index++ ); + checkResult( listeners, listeners.getPreCollectionRemoveListener(), parent, index++ ); + checkResult( listeners, listeners.getPostCollectionRemoveListener(), parent, index++ ); + checkNumberOfResults( listeners, index ); + } + + public void testDeleteParentAndChild() { + CollectionListeners listeners = new CollectionListeners( getSessions() ); + ParentWithCollection parent = createParentWithOneChild( "parent", "child" ); + Child child = ( Child ) parent.getChildren().iterator().next(); + listeners.clear(); + Session s = openSession(); + Transaction tx = s.beginTransaction(); + parent = ( ParentWithCollection ) s.get( parent.getClass(), parent.getId() ); + if ( child instanceof ChildEntity ) { + child = ( Child ) s.get( child.getClass(), ( ( ChildEntity ) child ).getId() ); + } + parent.removeChild( child ); + if ( child instanceof ChildEntity ) { + s.delete( child ); + } + s.delete( parent ); + tx.commit(); + s.close(); + int index = 0; + checkResult( listeners, listeners.getInitializeCollectionListener(), parent, index++ ); + if ( child.hasBidirectionalManyToMany() ) { + checkResult( listeners, listeners.getInitializeCollectionListener(), child, index++ ); + } + checkResult( listeners, listeners.getPreCollectionRemoveListener(), parent, index++ ); + checkResult( listeners, listeners.getPostCollectionRemoveListener(), parent, index++ ); + if ( child.hasBidirectionalManyToMany() ) { + checkResult( listeners, listeners.getPreCollectionRemoveListener(), child, index++ ); + checkResult( listeners, listeners.getPostCollectionRemoveListener(), child, index++ ); + } + checkNumberOfResults( listeners, index ); + } + + public void testMoveChildToDifferentParent() { + CollectionListeners listeners = new CollectionListeners( getSessions() ); + ParentWithCollection parent = createParentWithOneChild( "parent", "child" ); + ParentWithCollection otherParent = createParentWithOneChild( "otherParent", "otherChild" ); + Child child = ( Child ) parent.getChildren().iterator().next(); + listeners.clear(); + Session s = openSession(); + Transaction tx = s.beginTransaction(); + parent = ( ParentWithCollection ) s.get( parent.getClass(), parent.getId() ); + otherParent = ( ParentWithCollection ) s.get( otherParent.getClass(), otherParent.getId() ); + if ( child instanceof ChildEntity ) { + child = ( Child ) s.get( child.getClass(), ( ( ChildEntity ) child ).getId() ); + } + parent.removeChild( child ); + otherParent.addChild( child ); + tx.commit(); + s.close(); + int index = 0; + if ( ( ( PersistentCollection ) parent.getChildren() ).wasInitialized() ) { + checkResult( listeners, listeners.getInitializeCollectionListener(), parent, index++ ); + } + if ( child.hasBidirectionalManyToMany() ) { + checkResult( listeners, listeners.getInitializeCollectionListener(), child, index++ ); + } + if ( ( ( PersistentCollection ) otherParent.getChildren() ).wasInitialized() ) { + checkResult( listeners, listeners.getInitializeCollectionListener(), otherParent, index++ ); + } + checkResult( listeners, listeners.getPreCollectionUpdateListener(), parent, index++ ); + checkResult( listeners, listeners.getPostCollectionUpdateListener(), parent, index++ ); + checkResult( listeners, listeners.getPreCollectionUpdateListener(), otherParent, index++ ); + checkResult( listeners, listeners.getPostCollectionUpdateListener(), otherParent, index++ ); + if ( child.hasBidirectionalManyToMany() ) { + checkResult( listeners, listeners.getPreCollectionUpdateListener(), child, index++ ); + checkResult( listeners, listeners.getPostCollectionUpdateListener(), child, index++ ); + } + checkNumberOfResults( listeners, index ); + } + + public void testMoveAllChildrenToDifferentParent() { + CollectionListeners listeners = new CollectionListeners( getSessions() ); + ParentWithCollection parent = createParentWithOneChild( "parent", "child" ); + ParentWithCollection otherParent = createParentWithOneChild( "otherParent", "otherChild" ); + Child child = ( Child ) parent.getChildren().iterator().next(); + listeners.clear(); + Session s = openSession(); + Transaction tx = s.beginTransaction(); + parent = ( ParentWithCollection ) s.get( parent.getClass(), parent.getId() ); + otherParent = ( ParentWithCollection ) s.get( otherParent.getClass(), otherParent.getId() ); + if ( child instanceof ChildEntity ) { + child = ( ChildEntity ) s.get( child.getClass(), ( ( ChildEntity ) child ).getId() ); + } + otherParent.addAllChildren( parent.getChildren() ); + parent.clearChildren(); + tx.commit(); + s.close(); + int index = 0; + if ( ( ( PersistentCollection ) parent.getChildren() ).wasInitialized() ) { + checkResult( listeners, listeners.getInitializeCollectionListener(), parent, index++ ); + } + if ( ( ( PersistentCollection ) otherParent.getChildren() ).wasInitialized() ) { + checkResult( listeners, listeners.getInitializeCollectionListener(), otherParent, index++ ); + } + if ( child.hasBidirectionalManyToMany() ) { + checkResult( listeners, listeners.getInitializeCollectionListener(), child, index++ ); + } + checkResult( listeners, listeners.getPreCollectionUpdateListener(), parent, index++ ); + checkResult( listeners, listeners.getPostCollectionUpdateListener(), parent, index++ ); + checkResult( listeners, listeners.getPreCollectionUpdateListener(), otherParent, index++ ); + checkResult( listeners, listeners.getPostCollectionUpdateListener(), otherParent, index++ ); + if ( child.hasBidirectionalManyToMany() ) { + checkResult( listeners, listeners.getPreCollectionUpdateListener(), child, index++ ); + checkResult( listeners, listeners.getPostCollectionUpdateListener(), child, index++ ); + } + checkNumberOfResults( listeners, index ); + } + + public void testMoveCollectionToDifferentParent() { + CollectionListeners listeners = new CollectionListeners( getSessions() ); + ParentWithCollection parent = createParentWithOneChild( "parent", "child" ); + ParentWithCollection otherParent = createParentWithOneChild( "otherParent", "otherChild" ); + listeners.clear(); + Session s = openSession(); + Transaction tx = s.beginTransaction(); + parent = ( ParentWithCollection ) s.get( parent.getClass(), parent.getId() ); + otherParent = ( ParentWithCollection ) s.get( otherParent.getClass(), otherParent.getId() ); + Collection otherCollectionOrig = otherParent.getChildren(); + otherParent.newChildren( parent.getChildren() ); + parent.newChildren( null ); + tx.commit(); + s.close(); + int index = 0; + Child otherChildOrig = null; + if ( ( ( PersistentCollection ) otherCollectionOrig ).wasInitialized() ) { + checkResult( listeners, listeners.getInitializeCollectionListener(), otherParent, otherCollectionOrig, index++ ); + otherChildOrig = ( Child ) otherCollectionOrig.iterator().next(); + if ( otherChildOrig.hasBidirectionalManyToMany() ) { + checkResult( listeners, listeners.getInitializeCollectionListener(), otherChildOrig, index++ ); + } + } + checkResult( listeners, listeners.getInitializeCollectionListener(), parent, otherParent.getChildren(), index++ ); + Child otherChild = ( Child ) otherParent.getChildren().iterator().next(); + if ( otherChild.hasBidirectionalManyToMany() ) { + checkResult( listeners, listeners.getInitializeCollectionListener(), otherChild, index++ ); + } + checkResult( listeners, listeners.getPreCollectionRemoveListener(), parent, otherParent.getChildren(), index++ ); + checkResult( listeners, listeners.getPostCollectionRemoveListener(), parent, otherParent.getChildren(), index++ ); + checkResult( listeners, listeners.getPreCollectionRemoveListener(), otherParent, otherCollectionOrig, index++ ); + checkResult( listeners, listeners.getPostCollectionRemoveListener(), otherParent, otherCollectionOrig, index++ ); + if ( otherChild.hasBidirectionalManyToMany() ) { + checkResult( listeners, listeners.getPreCollectionUpdateListener(), otherChildOrig, index++ ); + checkResult( listeners, listeners.getPostCollectionUpdateListener(), otherChildOrig, index++ ); + checkResult( listeners, listeners.getPreCollectionUpdateListener(), otherChild, index++ ); + checkResult( listeners, listeners.getPostCollectionUpdateListener(), otherChild, index++ ); + } + checkResult( listeners, listeners.getPreCollectionRecreateListener(), otherParent, index++ ); + checkResult( listeners, listeners.getPostCollectionRecreateListener(), otherParent, index++ ); + // there should also be pre- and post-recreate collection events for parent, but thats broken now; + // this is covered in BrokenCollectionEventTest + checkNumberOfResults( listeners, index ); + } + + public void testMoveCollectionToDifferentParentFlushMoveToDifferentParent() { + CollectionListeners listeners = new CollectionListeners( getSessions() ); + ParentWithCollection parent = createParentWithOneChild( "parent", "child" ); + ParentWithCollection otherParent = createParentWithOneChild( "otherParent", "otherChild" ); + ParentWithCollection otherOtherParent = createParentWithNoChildren( "otherParent" ); + listeners.clear(); + Session s = openSession(); + Transaction tx = s.beginTransaction(); + parent = ( ParentWithCollection ) s.get( parent.getClass(), parent.getId() ); + otherParent = ( ParentWithCollection ) s.get( otherParent.getClass(), otherParent.getId() ); + otherOtherParent = ( ParentWithCollection ) s.get( otherOtherParent.getClass(), otherOtherParent.getId() ); + Collection otherCollectionOrig = otherParent.getChildren(); + Collection otherOtherCollectionOrig = otherOtherParent.getChildren(); + otherParent.newChildren( parent.getChildren() ); + parent.newChildren( null ); + s.flush(); + otherOtherParent.newChildren( otherParent.getChildren() ); + otherParent.newChildren( null ); + tx.commit(); + s.close(); + int index = 0; + Child otherChildOrig = null; + if ( ( ( PersistentCollection ) otherCollectionOrig ).wasInitialized() ) { + checkResult( listeners, listeners.getInitializeCollectionListener(), otherParent, otherCollectionOrig, index++ ); + otherChildOrig = ( Child ) otherCollectionOrig.iterator().next(); + if ( otherChildOrig.hasBidirectionalManyToMany() ) { + checkResult( listeners, listeners.getInitializeCollectionListener(), otherChildOrig, index++ ); + } + } + checkResult( listeners, listeners.getInitializeCollectionListener(), parent, otherOtherParent.getChildren(), index++ ); + Child otherOtherChild = ( Child ) otherOtherParent.getChildren().iterator().next(); + if ( otherOtherChild.hasBidirectionalManyToMany() ) { + checkResult( listeners, listeners.getInitializeCollectionListener(), otherOtherChild, index++ ); + } + checkResult( listeners, listeners.getPreCollectionRemoveListener(), parent, otherOtherParent.getChildren(), index++ ); + checkResult( listeners, listeners.getPostCollectionRemoveListener(), parent, otherOtherParent.getChildren(), index++ ); + checkResult( listeners, listeners.getPreCollectionRemoveListener(), otherParent, otherCollectionOrig, index++ ); + checkResult( listeners, listeners.getPostCollectionRemoveListener(), otherParent, otherCollectionOrig, index++ ); + if ( otherOtherChild.hasBidirectionalManyToMany() ) { + checkResult( listeners, listeners.getPreCollectionUpdateListener(), otherChildOrig, index++ ); + checkResult( listeners, listeners.getPostCollectionUpdateListener(), otherChildOrig, index++ ); + checkResult( listeners, listeners.getPreCollectionUpdateListener(), otherOtherChild, index++ ); + checkResult( listeners, listeners.getPostCollectionUpdateListener(), otherOtherChild, index++ ); + } + checkResult( listeners, listeners.getPreCollectionRecreateListener(), otherParent, otherOtherParent.getChildren(), index++ ); + checkResult( listeners, listeners.getPostCollectionRecreateListener(), otherParent, otherOtherParent.getChildren(), index++ ); + if ( ( ( PersistentCollection ) otherOtherCollectionOrig ).wasInitialized() ) { + checkResult( listeners, listeners.getInitializeCollectionListener(), otherOtherParent, otherOtherCollectionOrig, index++ ); + } + checkResult( listeners, listeners.getPreCollectionRemoveListener(), otherParent, otherOtherParent.getChildren(), index++ ); + checkResult( listeners, listeners.getPostCollectionRemoveListener(), otherParent, otherOtherParent.getChildren(), index++ ); + checkResult( listeners, listeners.getPreCollectionRemoveListener(), otherOtherParent, otherOtherCollectionOrig, index++ ); + checkResult( listeners, listeners.getPostCollectionRemoveListener(), otherOtherParent, otherOtherCollectionOrig, index++ ); + if ( otherOtherChild.hasBidirectionalManyToMany() ) { + checkResult( listeners, listeners.getPreCollectionUpdateListener(), otherOtherChild, index++ ); + checkResult( listeners, listeners.getPostCollectionUpdateListener(), otherOtherChild, index++ ); + } + checkResult( listeners, listeners.getPreCollectionRecreateListener(), otherOtherParent, index++ ); + checkResult( listeners, listeners.getPostCollectionRecreateListener(), otherOtherParent, index++ ); + // there should also be pre- and post-recreate collection events for parent, and otherParent + // but thats broken now; this is covered in BrokenCollectionEventTest + checkNumberOfResults( listeners, index ); + } + + protected ParentWithCollection createParentWithNullChildren(String parentName) { + Session s = openSession(); + Transaction tx = s.beginTransaction(); + ParentWithCollection parent = createParent( parentName ); + s.save( parent ); + tx.commit(); + s.close(); + return parent; + } + + protected ParentWithCollection createParentWithNoChildren(String parentName) { + Session s = openSession(); + Transaction tx = s.beginTransaction(); + ParentWithCollection parent = createParent( parentName ); + parent.newChildren( createCollection() ); + s.save( parent ); + tx.commit(); + s.close(); + return parent; + } + + protected ParentWithCollection createParentWithOneChild(String parentName, String ChildName) { + Session s = openSession(); + Transaction tx = s.beginTransaction(); + ParentWithCollection parent = createParent( parentName ); + parent.newChildren( createCollection() ); + parent.addChild( ChildName ); + s.save( parent ); + tx.commit(); + s.close(); + return parent; + } + + protected Collection getParents( Child child ) { + return ( ( child instanceof ChildWithBidirectionalManyToMany ) + ? ( ( ChildWithBidirectionalManyToMany ) child ).getParents() + : null ); + } + protected void checkResult(CollectionListeners listeners, + CollectionListeners.Listener listenerExpected, + ParentWithCollection parent, + int index) { + checkResult( listeners, listenerExpected, parent, parent.getChildren(), index ); + } + protected void checkResult(CollectionListeners listeners, + CollectionListeners.Listener listenerExpected, + Child child, + int index) { + checkResult( listeners, listenerExpected, child, getParents( child ), index ); + } + + protected void checkResult(CollectionListeners listeners, + CollectionListeners.Listener listenerExpected, + Object ownerExpected, + Collection collExpected, + int index) { + assertSame( listenerExpected, listeners.getListenersCalled().get( index ) ); + assertSame( + ownerExpected, + ( ( AbstractCollectionEvent ) listeners.getEvents().get( index ) ).getAffectedOwner() + ); + assertSame( + collExpected, ( ( AbstractCollectionEvent ) listeners.getEvents().get( index ) ).getCollection() + ); + } + + protected void checkNumberOfResults(CollectionListeners listeners, int nEventsExpected) { + assertEquals( nEventsExpected, listeners.getListenersCalled().size() ); + assertEquals( nEventsExpected, listeners.getEvents().size() ); + } +} diff --git a/testsuite/src/test/java/org/hibernate/test/event/collection/AbstractParentWithCollection.java b/testsuite/src/test/java/org/hibernate/test/event/collection/AbstractParentWithCollection.java new file mode 100644 index 0000000000..2d712e4a72 --- /dev/null +++ b/testsuite/src/test/java/org/hibernate/test/event/collection/AbstractParentWithCollection.java @@ -0,0 +1,100 @@ +//$Id: $ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2007, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution statements + * applied by the authors. + * + * All third-party contributions are distributed under license by Red Hat + * Middleware LLC. This copyrighted material is made available to anyone + * wishing to use, modify, copy, or redistribute it subject to the terms + * and conditions of the GNU Lesser General Public License, as published by + * the Free Software Foundation. This program is distributed in the hope + * that it will be useful, but WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU Lesser General Public License for more details. You should + * have received a copy of the GNU Lesser General Public License along with + * this distribution; if not, write to: Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor Boston, MA 02110-1301 USA + */ +package org.hibernate.test.event.collection; + +import java.util.Collection; + +/** + * + * @author Gail Badner + */ +public abstract class AbstractParentWithCollection implements ParentWithCollection { + private Long id; + private String name; + + private Collection children; + + public AbstractParentWithCollection() { + } + + public AbstractParentWithCollection(String name) { + this.name = name; + } + + public void newChildren(Collection collection) { + setChildren( collection ); + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Collection getChildren() { + return children; + } + + public void setChildren(Collection children) { + this.children = children; + } + + public Child addChild(String name) { + Child child = createChild( name ); + addChild( child ); + return child; + } + + public void addChild(Child child) { + if ( child != null ) { + children.add( child ); + } + } + + public void addAllChildren(Collection children) { + this.children.addAll( children ); + } + + public void removeChild(Child child) { + children.remove( child ); + } + + public void removeAllChildren(Collection children) { + children.removeAll( children ); + } + + public void clearChildren() { + if ( children != null && !children.isEmpty() ) { + this.children.clear(); + } + } +} diff --git a/testsuite/src/test/java/org/hibernate/test/event/collection/BrokenCollectionEventTest.java b/testsuite/src/test/java/org/hibernate/test/event/collection/BrokenCollectionEventTest.java new file mode 100644 index 0000000000..9606d3c6cb --- /dev/null +++ b/testsuite/src/test/java/org/hibernate/test/event/collection/BrokenCollectionEventTest.java @@ -0,0 +1,322 @@ +//$Id: $ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2007, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution statements + * applied by the authors. + * + * All third-party contributions are distributed under license by Red Hat + * Middleware LLC. This copyrighted material is made available to anyone + * wishing to use, modify, copy, or redistribute it subject to the terms + * and conditions of the GNU Lesser General Public License, as published by + * the Free Software Foundation. This program is distributed in the hope + * that it will be useful, but WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU Lesser General Public License for more details. You should + * have received a copy of the GNU Lesser General Public License along with + * this distribution; if not, write to: Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor Boston, MA 02110-1301 USA + */ +package org.hibernate.test.event.collection; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; + +import junit.framework.Test; + +import org.hibernate.Session; +import org.hibernate.Transaction; +import org.hibernate.collection.PersistentCollection; +import org.hibernate.event.AbstractCollectionEvent; +import org.hibernate.junit.functional.FunctionalTestCase; +import org.hibernate.junit.functional.FunctionalTestClassTestSuite; +import org.hibernate.test.event.collection.association.bidirectional.manytomany.ChildWithBidirectionalManyToMany; +import org.hibernate.test.event.collection.association.unidirectional.ParentWithCollectionOfEntities; + +/** + * + * @author Gail Badner + * + * These tests are known to fail. When the functionality is corrected, the + * corresponding method will be moved into AbstractCollectionEventTest. + */ +public class BrokenCollectionEventTest extends FunctionalTestCase { + + public BrokenCollectionEventTest(String string) { + super( string ); + } + + public static Test suite() { + return new FunctionalTestClassTestSuite( BrokenCollectionEventTest.class ); + } + + public String[] getMappings() { + return new String[] { "event/collection/association/unidirectional/onetomany/UnidirectionalOneToManySetMapping.hbm.xml" }; + } + + public ParentWithCollection createParent(String name) { + return new ParentWithCollectionOfEntities( name ); + } + + public Collection createCollection() { + return new HashSet(); + } + + protected void cleanupTest() { + ParentWithCollection dummyParent = createParent( "dummyParent" ); + dummyParent.setChildren( createCollection() ); + Child dummyChild = dummyParent.addChild( "dummyChild" ); + Session s = openSession(); + Transaction tx = s.beginTransaction(); + List children = s.createCriteria( dummyChild.getClass() ).list(); + List parents = s.createCriteria( dummyParent.getClass() ).list(); + for ( Iterator it = parents.iterator(); it.hasNext(); ) { + ParentWithCollection parent = ( ParentWithCollection ) it.next(); + parent.clearChildren(); + s.delete( parent ); + } + for ( Iterator it = children.iterator(); it.hasNext(); ) { + s.delete( it.next() ); + } + tx.commit(); + s.close(); + } + + public void testUpdateDetachedParentNoChildrenToNullFailureExpected() { + CollectionListeners listeners = new CollectionListeners( getSessions() ); + ParentWithCollection parent = createParentWithNoChildren( "parent" ); + listeners.clear(); + assertEquals( 0, parent.getChildren().size() ); + Session s = openSession(); + Transaction tx = s.beginTransaction(); + Collection oldCollection = parent.getChildren(); + parent.newChildren( null ); + s.update( parent ); + tx.commit(); + s.close(); + int index = 0; + checkResult( listeners, listeners.getPreCollectionRemoveListener(), parent, oldCollection, index++ ); + checkResult( listeners, listeners.getPostCollectionRemoveListener(), parent, oldCollection, index++ ); + // pre- and post- collection recreate events should be created when updating an entity with a "null" collection + checkResult( listeners, listeners.getPreCollectionRecreateListener(), parent, index++ ); + checkResult( listeners, listeners.getPostCollectionRecreateListener(), parent, index++ ); + checkNumberOfResults( listeners, index ); + } + + // The following fails for the same reason as testUpdateDetachedParentNoChildrenToNullFailureExpected + // When that issue is fixed, this one should also be fixed and moved into AbstractCollectionEventTest. + /* + public void testUpdateDetachedParentOneChildToNullFailureExpected() { + CollectionListeners listeners = new CollectionListeners( getSessions() ); + AbstractParentWithCollection parent = createParentWithOneChild( "parent", "child" ); + Child oldChild = ( Child ) parent.getChildren().iterator().next(); + assertEquals( 1, parent.getChildren().size() ); + listeners.clear(); + Session s = openSession(); + Transaction tx = s.beginTransaction(); + Collection oldCollection = parent.getChildren(); + parent.newChildren( null ); + s.update( parent ); + tx.commit(); + s.close(); + int index = 0; + checkResult( listeners, listeners.getPreCollectionRemoveListener(), parent, oldCollection, index++ ); + checkResult( listeners, listeners.getPostCollectionRemoveListener(), parent, oldCollection, index++ ); + if ( oldChild.hasBidirectionalManyToMany() ) { + checkResult( listeners, listeners.getPreCollectionUpdateListener(), oldChild, index++ ); + checkResult( listeners, listeners.getPostCollectionUpdateListener(), oldChild, index++ ); + } + // pre- and post- collection recreate events should be created when updating an entity with a "null" collection + checkResult( listeners, listeners.getPreCollectionRecreateListener(), parent, index++ ); + checkResult( listeners, listeners.getPostCollectionRecreateListener(), parent, index++ ); + checkNumberOfResults( listeners, index ); + } + */ + + public void testSaveParentNullChildrenFailureExpected() { + CollectionListeners listeners = new CollectionListeners( getSessions() ); + ParentWithCollection parent = createParentWithNullChildren( "parent" ); + assertNull( parent.getChildren() ); + int index = 0; + // pre- and post- collection recreate events should be created when creating an entity with a "null" collection + checkResult( listeners, listeners.getPreCollectionRecreateListener(), parent, index++ ); + checkResult( listeners, listeners.getPostCollectionRecreateListener(), parent, index++ ); + checkNumberOfResults( listeners, index ); + listeners.clear(); + Session s = openSession(); + Transaction tx = s.beginTransaction(); + parent = ( ParentWithCollection ) s.get( parent.getClass(), parent.getId() ); + tx.commit(); + s.close(); + assertNotNull( parent.getChildren() ); + checkNumberOfResults( listeners, 0 ); + } + + public void testUpdateParentNoChildrenToNullFailureExpected() { + CollectionListeners listeners = new CollectionListeners( getSessions() ); + ParentWithCollection parent = createParentWithNoChildren( "parent" ); + listeners.clear(); + assertEquals( 0, parent.getChildren().size() ); + Session s = openSession(); + Transaction tx = s.beginTransaction(); + parent = ( ParentWithCollection ) s.get( parent.getClass(), parent.getId() ); + Collection oldCollection = parent.getChildren(); + parent.newChildren( null ); + tx.commit(); + s.close(); + int index = 0; + if ( ( ( PersistentCollection ) oldCollection ).wasInitialized() ) { + checkResult( listeners, listeners.getInitializeCollectionListener(), parent, oldCollection, index++ ); + } + checkResult( listeners, listeners.getPreCollectionRemoveListener(), parent, oldCollection, index++ ); + checkResult( listeners, listeners.getPostCollectionRemoveListener(), parent, oldCollection, index++ ); + // pre- and post- collection recreate events should be created when updating an entity with a "null" collection + checkResult( listeners, listeners.getPreCollectionRecreateListener(), parent, index++ ); + checkResult( listeners, listeners.getPostCollectionRecreateListener(), parent, index++ ); + checkNumberOfResults( listeners, index ); + } + + + // The following two tests fail for the same reason as testUpdateParentNoChildrenToNullFailureExpected + // When that issue is fixed, this one should also be fixed and moved into AbstractCollectionEventTest. + /* + public void testUpdateParentOneChildToNullFailureExpected() { + CollectionListeners listeners = new CollectionListeners( getSessions() ); + AbstractParentWithCollection parent = createParentWithOneChild( "parent", "child" ); + Child oldChild = ( Child ) parent.getChildren().iterator().next(); + assertEquals( 1, parent.getChildren().size() ); + listeners.clear(); + Session s = openSession(); + Transaction tx = s.beginTransaction(); + parent = ( AbstractParentWithCollection ) s.get( parent.getClass(), parent.getId() ); + if ( oldChild instanceof ChildEntity ) { + oldChild = ( Child ) s.get( oldChild.getClass(), ( ( ChildEntity ) oldChild ).getId() ); + } + Collection oldCollection = parent.getChildren(); + parent.newChildren( null ); + tx.commit(); + s.close(); + int index = 0; + if ( ( ( PersistentCollection ) oldCollection ).wasInitialized() ) { + checkResult( listeners, listeners.getInitializeCollectionListener(), parent, oldCollection, index++ ); + } + if ( oldChild.hasBidirectionalManyToMany() && ( ( PersistentCollection ) getParents( oldChild ) ).wasInitialized() ) { + checkResult( listeners, listeners.getInitializeCollectionListener(), oldChild, index++ ); + } + checkResult( listeners, listeners.getPreCollectionRemoveListener(), parent, oldCollection, index++ ); + checkResult( listeners, listeners.getPostCollectionRemoveListener(), parent, oldCollection, index++ ); + if ( oldChild.hasBidirectionalManyToMany() ) { + checkResult( listeners, listeners.getPreCollectionUpdateListener(), oldChild, index++ ); + checkResult( listeners, listeners.getPostCollectionUpdateListener(), oldChild, index++ ); + } + // pre- and post- collection recreate events should be created when updating an entity with a "null" collection + checkResult( listeners, listeners.getPreCollectionRecreateListener(), parent, index++ ); + checkResult( listeners, listeners.getPostCollectionRecreateListener(), parent, index++ ); + checkNumberOfResults( listeners, index ); + } + + public void testUpdateMergedParentOneChildToNullFailureExpected() { + CollectionListeners listeners = new CollectionListeners( getSessions() ); + AbstractParentWithCollection parent = createParentWithOneChild( "parent", "child" ); + assertEquals( 1, parent.getChildren().size() ); + listeners.clear(); + Session s = openSession(); + Transaction tx = s.beginTransaction(); + parent = ( AbstractParentWithCollection ) s.merge( parent ); + Collection oldCollection = parent.getChildren(); + parent.newChildren( null ); + tx.commit(); + s.close(); + int index = 0; + Child oldChild = ( Child ) oldCollection.iterator().next(); + if ( oldChild.hasBidirectionalManyToMany() && ( ( PersistentCollection ) getParents( oldChild ) ).wasInitialized() ) { + checkResult( listeners, listeners.getInitializeCollectionListener(), oldChild, index++ ); + } + checkResult( listeners, listeners.getPreCollectionRemoveListener(), parent, oldCollection, index++ ); + checkResult( listeners, listeners.getPostCollectionRemoveListener(), parent, oldCollection, index++ ); + if ( oldChild.hasBidirectionalManyToMany() ) { + checkResult( listeners, listeners.getPreCollectionUpdateListener(), oldChild, index++ ); + checkResult( listeners, listeners.getPostCollectionUpdateListener(), oldChild, index++ ); + } + // pre- and post- collection recreate events should be created when updating an entity with a "null" collection + checkResult( listeners, listeners.getPreCollectionRecreateListener(), parent, index++ ); + checkResult( listeners, listeners.getPostCollectionRecreateListener(), parent, index++ ); + checkNumberOfResults( listeners, index ); + } + */ + + private ParentWithCollection createParentWithNullChildren(String parentName) { + Session s = openSession(); + Transaction tx = s.beginTransaction(); + ParentWithCollection parent = createParent( parentName ); + s.save( parent ); + tx.commit(); + s.close(); + return parent; + } + + private ParentWithCollection createParentWithNoChildren(String parentName) { + Session s = openSession(); + Transaction tx = s.beginTransaction(); + ParentWithCollection parent = createParent( parentName ); + parent.setChildren( createCollection() ); + s.save( parent ); + tx.commit(); + s.close(); + return parent; + } + + private ParentWithCollection createParentWithOneChild(String parentName, String ChildName) { + Session s = openSession(); + Transaction tx = s.beginTransaction(); + ParentWithCollection parent = createParent( parentName ); + parent.setChildren( createCollection() ); + parent.addChild( ChildName ); + s.save( parent ); + tx.commit(); + s.close(); + return parent; + } + + private Collection getParents( Child child ) { + return ( ( child instanceof ChildWithBidirectionalManyToMany ) + ? ( ( ChildWithBidirectionalManyToMany ) child ).getParents() + : null ); + } + private void checkResult(CollectionListeners listeners, + CollectionListeners.Listener listenerExpected, + ParentWithCollection parent, + int index) { + checkResult( listeners, listenerExpected, parent, parent.getChildren(), index ); + } + private void checkResult(CollectionListeners listeners, + CollectionListeners.Listener listenerExpected, + Child child, + int index) { + checkResult( listeners, listenerExpected, child, getParents( child ), index ); + } + + private void checkResult(CollectionListeners listeners, + CollectionListeners.Listener listenerExpected, + Object ownerExpected, + Collection collExpected, + int index) { + assertSame( listenerExpected, listeners.getListenersCalled().get( index ) ); + assertSame( + ownerExpected, + ( ( AbstractCollectionEvent ) listeners.getEvents().get( index ) ).getAffectedOwner() + ); + assertSame( + collExpected, ( ( AbstractCollectionEvent ) listeners.getEvents().get( index ) ).getCollection() + ); + } + + private void checkNumberOfResults(CollectionListeners listeners, int nEventsExpected) { + assertEquals( nEventsExpected, listeners.getListenersCalled().size() ); + assertEquals( nEventsExpected, listeners.getEvents().size() ); + } +} \ No newline at end of file diff --git a/testsuite/src/test/java/org/hibernate/test/event/collection/Child.java b/testsuite/src/test/java/org/hibernate/test/event/collection/Child.java new file mode 100644 index 0000000000..42323f0cef --- /dev/null +++ b/testsuite/src/test/java/org/hibernate/test/event/collection/Child.java @@ -0,0 +1,35 @@ +//$Id: $ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2007, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution statements + * applied by the authors. + * + * All third-party contributions are distributed under license by Red Hat + * Middleware LLC. This copyrighted material is made available to anyone + * wishing to use, modify, copy, or redistribute it subject to the terms + * and conditions of the GNU Lesser General Public License, as published by + * the Free Software Foundation. This program is distributed in the hope + * that it will be useful, but WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU Lesser General Public License for more details. You should + * have received a copy of the GNU Lesser General Public License along with + * this distribution; if not, write to: Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor Boston, MA 02110-1301 USA + */ +package org.hibernate.test.event.collection; + +/** + * + * @author Gail Badner + */ +public interface Child { + + boolean hasBidirectionalManyToMany(); + + String getName(); + + void setName(String name); +} diff --git a/testsuite/src/test/java/org/hibernate/test/event/collection/ChildEntity.java b/testsuite/src/test/java/org/hibernate/test/event/collection/ChildEntity.java new file mode 100644 index 0000000000..4b622ac3be --- /dev/null +++ b/testsuite/src/test/java/org/hibernate/test/event/collection/ChildEntity.java @@ -0,0 +1,48 @@ +//$Id: $ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2007, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution statements + * applied by the authors. + * + * All third-party contributions are distributed under license by Red Hat + * Middleware LLC. This copyrighted material is made available to anyone + * wishing to use, modify, copy, or redistribute it subject to the terms + * and conditions of the GNU Lesser General Public License, as published by + * the Free Software Foundation. This program is distributed in the hope + * that it will be useful, but WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU Lesser General Public License for more details. You should + * have received a copy of the GNU Lesser General Public License along with + * this distribution; if not, write to: Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor Boston, MA 02110-1301 USA + */ +package org.hibernate.test.event.collection; + +/** + * + * @author Gail Badner + */ +public class ChildEntity extends ChildValue { + private Long id; + + + public ChildEntity() { + super(); + } + + public ChildEntity(String name) { + super( name ); + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + +} diff --git a/testsuite/src/test/java/org/hibernate/test/event/collection/ChildValue.java b/testsuite/src/test/java/org/hibernate/test/event/collection/ChildValue.java new file mode 100644 index 0000000000..4c9e8bebc6 --- /dev/null +++ b/testsuite/src/test/java/org/hibernate/test/event/collection/ChildValue.java @@ -0,0 +1,63 @@ +//$Id: $ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2007, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution statements + * applied by the authors. + * + * All third-party contributions are distributed under license by Red Hat + * Middleware LLC. This copyrighted material is made available to anyone + * wishing to use, modify, copy, or redistribute it subject to the terms + * and conditions of the GNU Lesser General Public License, as published by + * the Free Software Foundation. This program is distributed in the hope + * that it will be useful, but WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU Lesser General Public License for more details. You should + * have received a copy of the GNU Lesser General Public License along with + * this distribution; if not, write to: Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor Boston, MA 02110-1301 USA + */ +package org.hibernate.test.event.collection; + +/** + * + * @author Gail Badner + */ +public class ChildValue implements Child { + private String name; + + public ChildValue() { + } + + public ChildValue(String name) { + this.name = name; + } + + public boolean hasBidirectionalManyToMany() { + return false; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public boolean equals(Object otherChild) { + if ( this == otherChild ) { + return true; + } + if ( !( otherChild instanceof ChildValue ) ) { + return false; + } + return name.equals( ( ( ChildValue ) otherChild ).name ); + } + + public int hashCode() { + return name.hashCode(); + } +} diff --git a/testsuite/src/test/java/org/hibernate/test/event/collection/CollectionEventSuite.java b/testsuite/src/test/java/org/hibernate/test/event/collection/CollectionEventSuite.java new file mode 100644 index 0000000000..ae5a44a2f7 --- /dev/null +++ b/testsuite/src/test/java/org/hibernate/test/event/collection/CollectionEventSuite.java @@ -0,0 +1,54 @@ +//$Id: $ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2007, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution statements + * applied by the authors. + * + * All third-party contributions are distributed under license by Red Hat + * Middleware LLC. This copyrighted material is made available to anyone + * wishing to use, modify, copy, or redistribute it subject to the terms + * and conditions of the GNU Lesser General Public License, as published by + * the Free Software Foundation. This program is distributed in the hope + * that it will be useful, but WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU Lesser General Public License for more details. You should + * have received a copy of the GNU Lesser General Public License along with + * this distribution; if not, write to: Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor Boston, MA 02110-1301 USA + */ +package org.hibernate.test.event.collection; + +import junit.framework.Test; +import junit.framework.TestSuite; + +import org.hibernate.test.event.collection.association.bidirectional.manytomany.BidirectionalManyToManyBagToSetCollectionEventTest; +import org.hibernate.test.event.collection.association.bidirectional.manytomany.BidirectionalManyToManySetToSetCollectionEventTest; +import org.hibernate.test.event.collection.association.bidirectional.onetomany.BidirectionalOneToManyBagCollectionEventTest; +import org.hibernate.test.event.collection.association.bidirectional.onetomany.BidirectionalOneToManySetCollectionEventTest; +import org.hibernate.test.event.collection.association.unidirectional.manytomany.UnidirectionalManyToManyBagCollectionEventTest; +import org.hibernate.test.event.collection.association.unidirectional.onetomany.UnidirectionalOneToManyBagCollectionEventTest; +import org.hibernate.test.event.collection.association.unidirectional.onetomany.UnidirectionalOneToManySetCollectionEventTest; +import org.hibernate.test.event.collection.values.ValuesBagCollectionEventTest; + +/** + * + * @author Gail Badner + */ +public class CollectionEventSuite { + public static Test suite() { + TestSuite suite = new TestSuite( "Collection event test suite" ); + suite.addTest( BrokenCollectionEventTest.suite() ); + suite.addTest( BidirectionalManyToManyBagToSetCollectionEventTest.suite() ); + suite.addTest( BidirectionalManyToManySetToSetCollectionEventTest.suite() ); + suite.addTest( BidirectionalOneToManyBagCollectionEventTest.suite() ); + suite.addTest( BidirectionalOneToManySetCollectionEventTest.suite() ); + suite.addTest( UnidirectionalManyToManyBagCollectionEventTest.suite() ); + suite.addTest( UnidirectionalOneToManyBagCollectionEventTest.suite() ); + suite.addTest( UnidirectionalOneToManySetCollectionEventTest.suite() ); + suite.addTest( ValuesBagCollectionEventTest.suite() ); + return suite; + } +} \ No newline at end of file diff --git a/testsuite/src/test/java/org/hibernate/test/event/collection/CollectionListeners.java b/testsuite/src/test/java/org/hibernate/test/event/collection/CollectionListeners.java new file mode 100644 index 0000000000..ca25190570 --- /dev/null +++ b/testsuite/src/test/java/org/hibernate/test/event/collection/CollectionListeners.java @@ -0,0 +1,214 @@ +//$Id: $ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2007, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution statements + * applied by the authors. + * + * All third-party contributions are distributed under license by Red Hat + * Middleware LLC. This copyrighted material is made available to anyone + * wishing to use, modify, copy, or redistribute it subject to the terms + * and conditions of the GNU Lesser General Public License, as published by + * the Free Software Foundation. This program is distributed in the hope + * that it will be useful, but WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU Lesser General Public License for more details. You should + * have received a copy of the GNU Lesser General Public License along with + * this distribution; if not, write to: Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor Boston, MA 02110-1301 USA + */ +package org.hibernate.test.event.collection; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +import org.hibernate.SessionFactory; +import org.hibernate.event.AbstractCollectionEvent; +import org.hibernate.event.InitializeCollectionEvent; +import org.hibernate.event.InitializeCollectionEventListener; +import org.hibernate.event.PostCollectionRecreateEvent; +import org.hibernate.event.PostCollectionRecreateEventListener; +import org.hibernate.event.PostCollectionRemoveEvent; +import org.hibernate.event.PostCollectionRemoveEventListener; +import org.hibernate.event.PostCollectionUpdateEvent; +import org.hibernate.event.PostCollectionUpdateEventListener; +import org.hibernate.event.PreCollectionRecreateEvent; +import org.hibernate.event.PreCollectionRecreateEventListener; +import org.hibernate.event.PreCollectionRemoveEvent; +import org.hibernate.event.PreCollectionRemoveEventListener; +import org.hibernate.event.PreCollectionUpdateEvent; +import org.hibernate.event.PreCollectionUpdateEventListener; +import org.hibernate.event.def.DefaultInitializeCollectionEventListener; +import org.hibernate.impl.SessionFactoryImpl; + +/** + * Author: Gail Badner + */ +public class CollectionListeners { + + + public interface Listener extends Serializable { + void addEvent(AbstractCollectionEvent event, Listener listener); + } + + public static abstract class AbstractListener implements Listener { + + private final CollectionListeners listeners; + + protected AbstractListener( CollectionListeners listeners ) { + this.listeners = listeners; + } + + public void addEvent(AbstractCollectionEvent event, Listener listener) { + listeners.addEvent( event, listener ); + } + } + + public static class InitializeCollectionListener + extends DefaultInitializeCollectionEventListener + implements Listener { + private final CollectionListeners listeners; + private InitializeCollectionListener(CollectionListeners listeners) { + this.listeners = listeners; + } + public void onInitializeCollection(InitializeCollectionEvent event) { + super.onInitializeCollection( event ); + addEvent( event, this ); + } + public void addEvent(AbstractCollectionEvent event, Listener listener) { + listeners.addEvent( event, listener ); + } + } + + public static class PreCollectionRecreateListener extends AbstractListener + implements PreCollectionRecreateEventListener { + private PreCollectionRecreateListener(CollectionListeners listeners) { + super( listeners ); + } + public void onPreRecreateCollection(PreCollectionRecreateEvent event) { + addEvent( event, this ); + } + } + + public static class PostCollectionRecreateListener extends AbstractListener + implements PostCollectionRecreateEventListener { + private PostCollectionRecreateListener(CollectionListeners listeners) { + super( listeners ); + } + public void onPostRecreateCollection(PostCollectionRecreateEvent event) { + addEvent( event, this ); + } + } + + public static class PreCollectionRemoveListener extends AbstractListener + implements PreCollectionRemoveEventListener { + private PreCollectionRemoveListener(CollectionListeners listeners) { + super( listeners ); + } + public void onPreRemoveCollection(PreCollectionRemoveEvent event) { + addEvent( event, this ); + } + } + + public static class PostCollectionRemoveListener extends AbstractListener + implements PostCollectionRemoveEventListener { + private PostCollectionRemoveListener(CollectionListeners listeners) { + super( listeners ); + } + public void onPostRemoveCollection(PostCollectionRemoveEvent event) { + addEvent( event, this ); + } + } + + public static class PreCollectionUpdateListener extends AbstractListener + implements PreCollectionUpdateEventListener { + private PreCollectionUpdateListener(CollectionListeners listeners) { + super( listeners ); + } + public void onPreUpdateCollection(PreCollectionUpdateEvent event) { + addEvent( event, this ); + } + } + + public static class PostCollectionUpdateListener extends AbstractListener + implements PostCollectionUpdateEventListener { + private PostCollectionUpdateListener(CollectionListeners listeners) { + super( listeners ); + } + public void onPostUpdateCollection(PostCollectionUpdateEvent event) { + addEvent( event, this ); + } + } + + private final PreCollectionRecreateListener preCollectionRecreateListener; + private final InitializeCollectionListener initializeCollectionListener; + private final PreCollectionRemoveListener preCollectionRemoveListener; + private final PreCollectionUpdateListener preCollectionUpdateListener; + private final PostCollectionRecreateListener postCollectionRecreateListener; + private final PostCollectionRemoveListener postCollectionRemoveListener; + private final PostCollectionUpdateListener postCollectionUpdateListener; + + private List listenersCalled = new ArrayList(); + private List events = new ArrayList(); + + public CollectionListeners( SessionFactory sf) { + preCollectionRecreateListener = new PreCollectionRecreateListener( this ); + initializeCollectionListener = new InitializeCollectionListener( this ); + preCollectionRemoveListener = new PreCollectionRemoveListener( this ); + preCollectionUpdateListener = new PreCollectionUpdateListener( this ); + postCollectionRecreateListener = new PostCollectionRecreateListener( this ); + postCollectionRemoveListener = new PostCollectionRemoveListener( this ); + postCollectionUpdateListener = new PostCollectionUpdateListener( this ); + SessionFactoryImpl impl = ( SessionFactoryImpl ) sf; + impl.getEventListeners().setInitializeCollectionEventListeners( + new InitializeCollectionEventListener[] { initializeCollectionListener } + ); + impl.getEventListeners().setPreCollectionRecreateEventListeners( + new PreCollectionRecreateEventListener[] { preCollectionRecreateListener } + ); + impl.getEventListeners().setPostCollectionRecreateEventListeners( + new PostCollectionRecreateEventListener[] { postCollectionRecreateListener } + ); + impl.getEventListeners().setPreCollectionRemoveEventListeners( + new PreCollectionRemoveEventListener[] { preCollectionRemoveListener } + ); + impl.getEventListeners().setPostCollectionRemoveEventListeners( + new PostCollectionRemoveEventListener[] { postCollectionRemoveListener } + ); + impl.getEventListeners().setPreCollectionUpdateEventListeners( + new PreCollectionUpdateEventListener[] { preCollectionUpdateListener } + ); + impl.getEventListeners().setPostCollectionUpdateEventListeners( + new PostCollectionUpdateEventListener[] { postCollectionUpdateListener } + ); + } + + public void addEvent(AbstractCollectionEvent event, Listener listener) { + listenersCalled.add( listener ); + events.add( event ); + } + + public List getListenersCalled() { + return listenersCalled; + } + + public List getEvents() { + return events; + } + + public void clear() { + listenersCalled.clear(); + events.clear(); + } + + public PreCollectionRecreateListener getPreCollectionRecreateListener() { return preCollectionRecreateListener; } + public InitializeCollectionListener getInitializeCollectionListener() { return initializeCollectionListener; } + public PreCollectionRemoveListener getPreCollectionRemoveListener() { return preCollectionRemoveListener; } + public PreCollectionUpdateListener getPreCollectionUpdateListener() { return preCollectionUpdateListener; } + public PostCollectionRecreateListener getPostCollectionRecreateListener() { return postCollectionRecreateListener; } + public PostCollectionRemoveListener getPostCollectionRemoveListener() { return postCollectionRemoveListener; } + public PostCollectionUpdateListener getPostCollectionUpdateListener() { return postCollectionUpdateListener; } +} diff --git a/testsuite/src/test/java/org/hibernate/test/event/collection/ParentWithCollection.java b/testsuite/src/test/java/org/hibernate/test/event/collection/ParentWithCollection.java new file mode 100644 index 0000000000..2ee6e45c8d --- /dev/null +++ b/testsuite/src/test/java/org/hibernate/test/event/collection/ParentWithCollection.java @@ -0,0 +1,58 @@ +//$Id: $ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2007, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution statements + * applied by the authors. + * + * All third-party contributions are distributed under license by Red Hat + * Middleware LLC. This copyrighted material is made available to anyone + * wishing to use, modify, copy, or redistribute it subject to the terms + * and conditions of the GNU Lesser General Public License, as published by + * the Free Software Foundation. This program is distributed in the hope + * that it will be useful, but WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU Lesser General Public License for more details. You should + * have received a copy of the GNU Lesser General Public License along with + * this distribution; if not, write to: Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor Boston, MA 02110-1301 USA + */ +package org.hibernate.test.event.collection; + +import java.util.Collection; + +/** + * + * @author Gail Badner + */ +public interface ParentWithCollection { + void newChildren(Collection collection); + + Child createChild(String name); + + Long getId(); + + void setId(Long id); + + String getName(); + + void setName(String name); + + Collection getChildren(); + + void setChildren(Collection children); + + Child addChild(String name); + + void addChild(Child child); + + void addAllChildren(Collection children); + + void removeChild(Child child); + + void removeAllChildren(Collection children); + + void clearChildren(); +} diff --git a/testsuite/src/test/java/org/hibernate/test/event/collection/association/AbstractAssociationCollectionEventTest.java b/testsuite/src/test/java/org/hibernate/test/event/collection/association/AbstractAssociationCollectionEventTest.java new file mode 100644 index 0000000000..ee9adc5037 --- /dev/null +++ b/testsuite/src/test/java/org/hibernate/test/event/collection/association/AbstractAssociationCollectionEventTest.java @@ -0,0 +1,66 @@ +//$Id: $ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2007, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution statements + * applied by the authors. + * + * All third-party contributions are distributed under license by Red Hat + * Middleware LLC. This copyrighted material is made available to anyone + * wishing to use, modify, copy, or redistribute it subject to the terms + * and conditions of the GNU Lesser General Public License, as published by + * the Free Software Foundation. This program is distributed in the hope + * that it will be useful, but WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU Lesser General Public License for more details. You should + * have received a copy of the GNU Lesser General Public License along with + * this distribution; if not, write to: Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor Boston, MA 02110-1301 USA + */ +package org.hibernate.test.event.collection.association; + +import org.hibernate.test.event.collection.AbstractCollectionEventTest; +import org.hibernate.test.event.collection.CollectionListeners; +import org.hibernate.test.event.collection.ChildEntity; +import org.hibernate.test.event.collection.ParentWithCollection; +import org.hibernate.Session; +import org.hibernate.Transaction; + +/** + * + * @author Gail Badner + */ +public abstract class AbstractAssociationCollectionEventTest extends AbstractCollectionEventTest { + public AbstractAssociationCollectionEventTest(String string) { + super( string ); + } + + public void testDeleteParentButNotChild() { + CollectionListeners listeners = new CollectionListeners( getSessions() ); + ParentWithCollection parent = createParentWithOneChild( "parent", "child" ); + ChildEntity child = ( ChildEntity ) parent.getChildren().iterator().next(); + listeners.clear(); + Session s = openSession(); + Transaction tx = s.beginTransaction(); + parent = ( ParentWithCollection ) s.get( parent.getClass(), parent.getId() ); + child = ( ChildEntity ) s.get( child.getClass(), child.getId() ); + parent.removeChild( child ); + s.delete( parent ); + tx.commit(); + s.close(); + int index = 0; + checkResult( listeners, listeners.getInitializeCollectionListener(), parent, index++ ); + if ( child.hasBidirectionalManyToMany() ) { + checkResult( listeners, listeners.getInitializeCollectionListener(), child, index++ ); + } + checkResult( listeners, listeners.getPreCollectionRemoveListener(), parent, index++ ); + checkResult( listeners, listeners.getPostCollectionRemoveListener(), parent, index++ ); + if ( child.hasBidirectionalManyToMany() ) { + checkResult( listeners, listeners.getPreCollectionUpdateListener(), child, index++ ); + checkResult( listeners, listeners.getPostCollectionUpdateListener(), child, index++ ); + } + checkNumberOfResults( listeners, index ); + } +} diff --git a/testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/manytomany/BidirectionalManyToManyBagToSetCollectionEventTest.java b/testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/manytomany/BidirectionalManyToManyBagToSetCollectionEventTest.java new file mode 100644 index 0000000000..fd00ce8e66 --- /dev/null +++ b/testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/manytomany/BidirectionalManyToManyBagToSetCollectionEventTest.java @@ -0,0 +1,59 @@ +//$Id: $ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2007, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution statements + * applied by the authors. + * + * All third-party contributions are distributed under license by Red Hat + * Middleware LLC. This copyrighted material is made available to anyone + * wishing to use, modify, copy, or redistribute it subject to the terms + * and conditions of the GNU Lesser General Public License, as published by + * the Free Software Foundation. This program is distributed in the hope + * that it will be useful, but WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU Lesser General Public License for more details. You should + * have received a copy of the GNU Lesser General Public License along with + * this distribution; if not, write to: Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor Boston, MA 02110-1301 USA + */ +package org.hibernate.test.event.collection.association.bidirectional.manytomany; + +import java.util.ArrayList; +import java.util.Collection; + +import junit.framework.Test; + +import org.hibernate.junit.functional.FunctionalTestClassTestSuite; +import org.hibernate.test.event.collection.ParentWithCollection; +import org.hibernate.test.event.collection.association.AbstractAssociationCollectionEventTest; +import org.hibernate.test.event.collection.association.bidirectional.manytomany.ParentWithBidirectionalManyToMany; + +/** + * + * @author Gail Badner + */ +public class BidirectionalManyToManyBagToSetCollectionEventTest extends AbstractAssociationCollectionEventTest { + + public BidirectionalManyToManyBagToSetCollectionEventTest(String string) { + super( string ); + } + + public static Test suite() { + return new FunctionalTestClassTestSuite( BidirectionalManyToManyBagToSetCollectionEventTest.class ); + } + + public String[] getMappings() { + return new String[] { "event/collection/association/bidirectional/manytomany/BidirectionalManyToManyBagToSetMapping.hbm.xml" }; + } + + public ParentWithCollection createParent(String name) { + return new ParentWithBidirectionalManyToMany( name ); + } + + public Collection createCollection() { + return new ArrayList(); + } +} diff --git a/testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/manytomany/BidirectionalManyToManyBagToSetMapping.hbm.xml b/testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/manytomany/BidirectionalManyToManyBagToSetMapping.hbm.xml new file mode 100644 index 0000000000..31f8a1f4bf --- /dev/null +++ b/testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/manytomany/BidirectionalManyToManyBagToSetMapping.hbm.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/manytomany/BidirectionalManyToManySetToSetCollectionEventTest.java b/testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/manytomany/BidirectionalManyToManySetToSetCollectionEventTest.java new file mode 100644 index 0000000000..c8ec92b562 --- /dev/null +++ b/testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/manytomany/BidirectionalManyToManySetToSetCollectionEventTest.java @@ -0,0 +1,59 @@ +//$Id: $ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2007, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution statements + * applied by the authors. + * + * All third-party contributions are distributed under license by Red Hat + * Middleware LLC. This copyrighted material is made available to anyone + * wishing to use, modify, copy, or redistribute it subject to the terms + * and conditions of the GNU Lesser General Public License, as published by + * the Free Software Foundation. This program is distributed in the hope + * that it will be useful, but WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU Lesser General Public License for more details. You should + * have received a copy of the GNU Lesser General Public License along with + * this distribution; if not, write to: Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor Boston, MA 02110-1301 USA + */ +package org.hibernate.test.event.collection.association.bidirectional.manytomany; + +import java.util.Collection; +import java.util.HashSet; + +import junit.framework.Test; + +import org.hibernate.junit.functional.FunctionalTestClassTestSuite; +import org.hibernate.test.event.collection.ParentWithCollection; +import org.hibernate.test.event.collection.association.AbstractAssociationCollectionEventTest; +import org.hibernate.test.event.collection.association.bidirectional.manytomany.ParentWithBidirectionalManyToMany; + +/** + * + * @author Gail Badner + */ +public class BidirectionalManyToManySetToSetCollectionEventTest extends AbstractAssociationCollectionEventTest { + + public BidirectionalManyToManySetToSetCollectionEventTest(String string) { + super( string ); + } + + public static Test suite() { + return new FunctionalTestClassTestSuite( BidirectionalManyToManySetToSetCollectionEventTest.class ); + } + + public String[] getMappings() { + return new String[] { "event/collection/association/bidirectional/manytomany/BidirectionalManyToManySetToSetMapping.hbm.xml" }; + } + + public ParentWithCollection createParent(String name) { + return new ParentWithBidirectionalManyToMany( name ); + } + + public Collection createCollection() { + return new HashSet(); + } +} diff --git a/testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/manytomany/BidirectionalManyToManySetToSetMapping.hbm.xml b/testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/manytomany/BidirectionalManyToManySetToSetMapping.hbm.xml new file mode 100644 index 0000000000..4dbae99190 --- /dev/null +++ b/testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/manytomany/BidirectionalManyToManySetToSetMapping.hbm.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/manytomany/ChildWithBidirectionalManyToMany.java b/testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/manytomany/ChildWithBidirectionalManyToMany.java new file mode 100644 index 0000000000..771841e6f6 --- /dev/null +++ b/testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/manytomany/ChildWithBidirectionalManyToMany.java @@ -0,0 +1,66 @@ +//$Id: $ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2007, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution statements + * applied by the authors. + * + * All third-party contributions are distributed under license by Red Hat + * Middleware LLC. This copyrighted material is made available to anyone + * wishing to use, modify, copy, or redistribute it subject to the terms + * and conditions of the GNU Lesser General Public License, as published by + * the Free Software Foundation. This program is distributed in the hope + * that it will be useful, but WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU Lesser General Public License for more details. You should + * have received a copy of the GNU Lesser General Public License along with + * this distribution; if not, write to: Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor Boston, MA 02110-1301 USA + */ +package org.hibernate.test.event.collection.association.bidirectional.manytomany; + +import java.util.Collection; + +import org.hibernate.test.event.collection.ChildEntity; + +/** + * + * @author Gail Badner + */ +public class ChildWithBidirectionalManyToMany extends ChildEntity { + private Collection parents; + + public ChildWithBidirectionalManyToMany() { + } + + public ChildWithBidirectionalManyToMany(String name, Collection parents) { + super( name ); + this.parents = parents; + } + + public boolean hasBidirectionalManyToMany() { + return true; + } + + public Collection getParents() { + return parents; + } + + public void setParents(Collection parents) { + this.parents = parents; + } + + public void addParent(ParentWithBidirectionalManyToMany parent) { + if ( parent != null ) { + parents.add( parent ); + } + } + + public void removeParent(ParentWithBidirectionalManyToMany parent) { + if ( parent != null ) { + parents.remove( parent ); + } + } +} diff --git a/testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/manytomany/ParentWithBidirectionalManyToMany.java b/testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/manytomany/ParentWithBidirectionalManyToMany.java new file mode 100644 index 0000000000..f85addfb7a --- /dev/null +++ b/testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/manytomany/ParentWithBidirectionalManyToMany.java @@ -0,0 +1,105 @@ +//$Id: $ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2007, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution statements + * applied by the authors. + * + * All third-party contributions are distributed under license by Red Hat + * Middleware LLC. This copyrighted material is made available to anyone + * wishing to use, modify, copy, or redistribute it subject to the terms + * and conditions of the GNU Lesser General Public License, as published by + * the Free Software Foundation. This program is distributed in the hope + * that it will be useful, but WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU Lesser General Public License for more details. You should + * have received a copy of the GNU Lesser General Public License along with + * this distribution; if not, write to: Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor Boston, MA 02110-1301 USA + */ +package org.hibernate.test.event.collection.association.bidirectional.manytomany; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; + +import org.hibernate.test.event.collection.Child; +import org.hibernate.test.event.collection.AbstractParentWithCollection; + +/** + * + * @author Gail Badner + */ +public class ParentWithBidirectionalManyToMany extends AbstractParentWithCollection { + public ParentWithBidirectionalManyToMany() { + } + + public ParentWithBidirectionalManyToMany(String name) { + super( name ); + } + + public void newChildren(Collection children) { + if ( children == getChildren() ) { + return; + } + if ( getChildren() != null ) { + for ( Iterator it = getChildren().iterator(); it.hasNext(); ) { + ChildWithBidirectionalManyToMany child = ( ChildWithBidirectionalManyToMany ) it.next(); + child.removeParent( this ); + } + } + if ( children != null ) { + for ( Iterator it = children.iterator(); it.hasNext(); ) { + ChildWithBidirectionalManyToMany child = ( ChildWithBidirectionalManyToMany ) it.next(); + child.addParent( this ); + } + } + super.newChildren( children ); + } + + public Child createChild(String name) { + return new ChildWithBidirectionalManyToMany( name, new HashSet() ); + } + + public void addChild(Child child) { + super.addChild( child ); + ( ( ChildWithBidirectionalManyToMany ) child ).addParent( this ); + } + + public void addAllChildren(Collection children) { + super.addAllChildren( children ); + for ( Iterator it = children.iterator(); it.hasNext(); ) { + ChildWithBidirectionalManyToMany child = ( ChildWithBidirectionalManyToMany ) it.next(); + child.addParent( this ); + } + } + + public void removeChild(Child child) { + // Note: if the collection is a bag, the same child can be in the collection more than once + super.removeChild( child ); + // only remove the parent from the child's set if child is no longer in the collection + if ( ! getChildren().contains( child ) ) { + ( ( ChildWithBidirectionalManyToMany ) child ).removeParent( this ); + } + } + + public void removeAllChildren(Collection children) { + super.removeAllChildren( children ); + for ( Iterator it = children.iterator(); it.hasNext(); ) { + ChildWithBidirectionalManyToMany child = ( ChildWithBidirectionalManyToMany ) it.next(); + child.removeParent( this ); + } + } + + public void clearChildren() { + if ( getChildren() != null ) { + for ( Iterator it = getChildren().iterator(); it.hasNext(); ) { + ChildWithBidirectionalManyToMany child = ( ChildWithBidirectionalManyToMany ) it.next(); + child.removeParent( this ); + } + } + super.clearChildren(); + } +} diff --git a/testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/onetomany/BidirectionalOneToManyBagCollectionEventTest.java b/testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/onetomany/BidirectionalOneToManyBagCollectionEventTest.java new file mode 100644 index 0000000000..2449fdf511 --- /dev/null +++ b/testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/onetomany/BidirectionalOneToManyBagCollectionEventTest.java @@ -0,0 +1,65 @@ +//$Id: $ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2007, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution statements + * applied by the authors. + * + * All third-party contributions are distributed under license by Red Hat + * Middleware LLC. This copyrighted material is made available to anyone + * wishing to use, modify, copy, or redistribute it subject to the terms + * and conditions of the GNU Lesser General Public License, as published by + * the Free Software Foundation. This program is distributed in the hope + * that it will be useful, but WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU Lesser General Public License for more details. You should + * have received a copy of the GNU Lesser General Public License along with + * this distribution; if not, write to: Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor Boston, MA 02110-1301 USA + */ +package org.hibernate.test.event.collection.association.bidirectional.onetomany; + +import java.util.ArrayList; +import java.util.Collection; + +import junit.framework.Test; + +import org.hibernate.junit.functional.FunctionalTestClassTestSuite; +import org.hibernate.test.event.collection.Child; +import org.hibernate.test.event.collection.ParentWithCollection; +import org.hibernate.test.event.collection.association.AbstractAssociationCollectionEventTest; +import org.hibernate.test.event.collection.association.bidirectional.onetomany.ChildWithManyToOne; +import org.hibernate.test.event.collection.association.bidirectional.onetomany.ParentWithBidirectionalOneToMany; + +/** + * + * @author Gail Badner + */ +public class BidirectionalOneToManyBagCollectionEventTest extends AbstractAssociationCollectionEventTest { + + public BidirectionalOneToManyBagCollectionEventTest(String string) { + super( string ); + } + + public static Test suite() { + return new FunctionalTestClassTestSuite( BidirectionalOneToManyBagCollectionEventTest.class ); + } + + public String[] getMappings() { + return new String[] { "event/collection/association/bidirectional/onetomany/BidirectionalOneToManyBagMapping.hbm.xml" }; + } + + public ParentWithCollection createParent(String name) { + return new ParentWithBidirectionalOneToMany( name ); + } + + public Collection createCollection() { + return new ArrayList(); + } + + public Child createChild(String name) { + return new ChildWithManyToOne( name ); + } +} \ No newline at end of file diff --git a/testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/onetomany/BidirectionalOneToManyBagMapping.hbm.xml b/testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/onetomany/BidirectionalOneToManyBagMapping.hbm.xml new file mode 100644 index 0000000000..9c33a50ea1 --- /dev/null +++ b/testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/onetomany/BidirectionalOneToManyBagMapping.hbm.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/onetomany/BidirectionalOneToManySetCollectionEventTest.java b/testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/onetomany/BidirectionalOneToManySetCollectionEventTest.java new file mode 100644 index 0000000000..e41741c8c8 --- /dev/null +++ b/testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/onetomany/BidirectionalOneToManySetCollectionEventTest.java @@ -0,0 +1,65 @@ +//$Id: $ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2007, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution statements + * applied by the authors. + * + * All third-party contributions are distributed under license by Red Hat + * Middleware LLC. This copyrighted material is made available to anyone + * wishing to use, modify, copy, or redistribute it subject to the terms + * and conditions of the GNU Lesser General Public License, as published by + * the Free Software Foundation. This program is distributed in the hope + * that it will be useful, but WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU Lesser General Public License for more details. You should + * have received a copy of the GNU Lesser General Public License along with + * this distribution; if not, write to: Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor Boston, MA 02110-1301 USA + */ +package org.hibernate.test.event.collection.association.bidirectional.onetomany; + +import java.util.Collection; +import java.util.HashSet; + +import junit.framework.Test; + +import org.hibernate.junit.functional.FunctionalTestClassTestSuite; +import org.hibernate.test.event.collection.Child; +import org.hibernate.test.event.collection.ParentWithCollection; +import org.hibernate.test.event.collection.association.AbstractAssociationCollectionEventTest; +import org.hibernate.test.event.collection.association.bidirectional.onetomany.ChildWithManyToOne; +import org.hibernate.test.event.collection.association.bidirectional.onetomany.ParentWithBidirectionalOneToMany; + +/** + * + * @author Gail Badner + */ +public class BidirectionalOneToManySetCollectionEventTest extends AbstractAssociationCollectionEventTest { + + public BidirectionalOneToManySetCollectionEventTest(String string) { + super( string ); + } + + public static Test suite() { + return new FunctionalTestClassTestSuite( BidirectionalOneToManySetCollectionEventTest.class ); + } + + public String[] getMappings() { + return new String[] { "event/collection/association/bidirectional/onetomany/BidirectionalOneToManySetMapping.hbm.xml" }; + } + + public ParentWithCollection createParent(String name) { + return new ParentWithBidirectionalOneToMany( name ); + } + + public Collection createCollection() { + return new HashSet(); + } + + public Child createChild(String name) { + return new ChildWithManyToOne( name ); + } +} diff --git a/testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/onetomany/BidirectionalOneToManySetMapping.hbm.xml b/testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/onetomany/BidirectionalOneToManySetMapping.hbm.xml new file mode 100644 index 0000000000..9ca7316ae0 --- /dev/null +++ b/testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/onetomany/BidirectionalOneToManySetMapping.hbm.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/onetomany/ChildWithManyToOne.java b/testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/onetomany/ChildWithManyToOne.java new file mode 100644 index 0000000000..c6d0105a48 --- /dev/null +++ b/testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/onetomany/ChildWithManyToOne.java @@ -0,0 +1,47 @@ +//$Id: $ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2007, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution statements + * applied by the authors. + * + * All third-party contributions are distributed under license by Red Hat + * Middleware LLC. This copyrighted material is made available to anyone + * wishing to use, modify, copy, or redistribute it subject to the terms + * and conditions of the GNU Lesser General Public License, as published by + * the Free Software Foundation. This program is distributed in the hope + * that it will be useful, but WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU Lesser General Public License for more details. You should + * have received a copy of the GNU Lesser General Public License along with + * this distribution; if not, write to: Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor Boston, MA 02110-1301 USA + */ +package org.hibernate.test.event.collection.association.bidirectional.onetomany; + +import org.hibernate.test.event.collection.ChildEntity; +import org.hibernate.test.event.collection.ParentWithCollection; + +/** + * @author Gail Badner + */ +public class ChildWithManyToOne extends ChildEntity { + private ParentWithCollection parent; + + public ChildWithManyToOne() { + } + + public ChildWithManyToOne(String name) { + super( name ); + } + + public ParentWithCollection getParent() { + return parent; + } + + public void setParent(ParentWithCollection parent) { + this.parent = parent; + } +} diff --git a/testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/onetomany/ParentWithBidirectionalOneToMany.java b/testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/onetomany/ParentWithBidirectionalOneToMany.java new file mode 100644 index 0000000000..a73cd6859b --- /dev/null +++ b/testsuite/src/test/java/org/hibernate/test/event/collection/association/bidirectional/onetomany/ParentWithBidirectionalOneToMany.java @@ -0,0 +1,85 @@ +//$Id: $ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2007, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution statements + * applied by the authors. + * + * All third-party contributions are distributed under license by Red Hat + * Middleware LLC. This copyrighted material is made available to anyone + * wishing to use, modify, copy, or redistribute it subject to the terms + * and conditions of the GNU Lesser General Public License, as published by + * the Free Software Foundation. This program is distributed in the hope + * that it will be useful, but WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU Lesser General Public License for more details. You should + * have received a copy of the GNU Lesser General Public License along with + * this distribution; if not, write to: Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor Boston, MA 02110-1301 USA + */ +package org.hibernate.test.event.collection.association.bidirectional.onetomany; + +import java.util.Collection; +import java.util.Iterator; + +import org.hibernate.test.event.collection.Child; +import org.hibernate.test.event.collection.AbstractParentWithCollection; + +/** + * + * @author Gail Badner + */ +public class ParentWithBidirectionalOneToMany extends AbstractParentWithCollection { + public ParentWithBidirectionalOneToMany() { + } + + public ParentWithBidirectionalOneToMany(String name) { + super( name ); + } + + public Child createChild( String name ) { + return new ChildWithManyToOne( name ); + } + + public Child addChild(String name) { + Child child = createChild( name ); + addChild( child ); + return child; + } + + public void addChild(Child child) { + super.addChild( child ); + ( ( ChildWithManyToOne ) child ).setParent( this ); + } + + public void newChildren(Collection children) { + if ( children == getChildren() ) { + return; + } + if ( getChildren() != null ) { + for ( Iterator it = getChildren().iterator(); it.hasNext(); ) { + ChildWithManyToOne child = ( ChildWithManyToOne ) it.next(); + child.setParent( null ); + } + } + if ( children != null ) { + for ( Iterator it = children.iterator(); it.hasNext(); ) { + ChildWithManyToOne child = ( ChildWithManyToOne ) it.next(); + child.setParent( this ); + } + } + super.newChildren( children ); + } + + public void removeChild(Child child) { + // Note: there can be more than one child in the collection + super.removeChild( child ); + // only set the parent to null if child is no longer in the bag + if ( ! getChildren().contains( child ) ) { + ( ( ChildWithManyToOne ) child ).setParent( null ); + } + } + +} diff --git a/testsuite/src/test/java/org/hibernate/test/event/collection/association/unidirectional/ParentWithCollectionOfEntities.java b/testsuite/src/test/java/org/hibernate/test/event/collection/association/unidirectional/ParentWithCollectionOfEntities.java new file mode 100644 index 0000000000..0b8e995fc3 --- /dev/null +++ b/testsuite/src/test/java/org/hibernate/test/event/collection/association/unidirectional/ParentWithCollectionOfEntities.java @@ -0,0 +1,43 @@ +//$Id: $ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2007, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution statements + * applied by the authors. + * + * All third-party contributions are distributed under license by Red Hat + * Middleware LLC. This copyrighted material is made available to anyone + * wishing to use, modify, copy, or redistribute it subject to the terms + * and conditions of the GNU Lesser General Public License, as published by + * the Free Software Foundation. This program is distributed in the hope + * that it will be useful, but WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU Lesser General Public License for more details. You should + * have received a copy of the GNU Lesser General Public License along with + * this distribution; if not, write to: Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor Boston, MA 02110-1301 USA + */ +package org.hibernate.test.event.collection.association.unidirectional; + +import org.hibernate.test.event.collection.AbstractParentWithCollection; +import org.hibernate.test.event.collection.Child; +import org.hibernate.test.event.collection.ChildEntity; + +/** + * @author Gail Badner + */ +public class ParentWithCollectionOfEntities extends AbstractParentWithCollection { + + public ParentWithCollectionOfEntities() { + } + + public ParentWithCollectionOfEntities(String name) { + super( name ); + } + + public Child createChild(String name) { + return new ChildEntity( name ); + } +} diff --git a/testsuite/src/test/java/org/hibernate/test/event/collection/association/unidirectional/manytomany/UnidirectionalManyToManyBagCollectionEventTest.java b/testsuite/src/test/java/org/hibernate/test/event/collection/association/unidirectional/manytomany/UnidirectionalManyToManyBagCollectionEventTest.java new file mode 100644 index 0000000000..d7c52b3dfd --- /dev/null +++ b/testsuite/src/test/java/org/hibernate/test/event/collection/association/unidirectional/manytomany/UnidirectionalManyToManyBagCollectionEventTest.java @@ -0,0 +1,65 @@ +//$Id: $ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2007, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution statements + * applied by the authors. + * + * All third-party contributions are distributed under license by Red Hat + * Middleware LLC. This copyrighted material is made available to anyone + * wishing to use, modify, copy, or redistribute it subject to the terms + * and conditions of the GNU Lesser General Public License, as published by + * the Free Software Foundation. This program is distributed in the hope + * that it will be useful, but WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU Lesser General Public License for more details. You should + * have received a copy of the GNU Lesser General Public License along with + * this distribution; if not, write to: Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor Boston, MA 02110-1301 USA + */ +package org.hibernate.test.event.collection.association.unidirectional.manytomany; + +import java.util.ArrayList; +import java.util.Collection; + +import junit.framework.Test; + +import org.hibernate.junit.functional.FunctionalTestClassTestSuite; +import org.hibernate.test.event.collection.Child; +import org.hibernate.test.event.collection.ChildEntity; +import org.hibernate.test.event.collection.ParentWithCollection; +import org.hibernate.test.event.collection.association.AbstractAssociationCollectionEventTest; +import org.hibernate.test.event.collection.association.unidirectional.ParentWithCollectionOfEntities; + +/** + * + * @author Gail Badner + */ +public class UnidirectionalManyToManyBagCollectionEventTest extends AbstractAssociationCollectionEventTest { + + public UnidirectionalManyToManyBagCollectionEventTest(String string) { + super( string ); + } + + public static Test suite() { + return new FunctionalTestClassTestSuite( UnidirectionalManyToManyBagCollectionEventTest.class ); + } + + public String[] getMappings() { + return new String[] { "event/collection/association/unidirectional/manytomany/UnidirectionalManyToManyBagMapping.hbm.xml" }; + } + + public ParentWithCollection createParent(String name) { + return new ParentWithCollectionOfEntities( name ); + } + + public Collection createCollection() { + return new ArrayList(); + } + + public Child createChild(String name) { + return new ChildEntity( name ); + } +} diff --git a/testsuite/src/test/java/org/hibernate/test/event/collection/association/unidirectional/manytomany/UnidirectionalManyToManyBagMapping.hbm.xml b/testsuite/src/test/java/org/hibernate/test/event/collection/association/unidirectional/manytomany/UnidirectionalManyToManyBagMapping.hbm.xml new file mode 100644 index 0000000000..938da8c590 --- /dev/null +++ b/testsuite/src/test/java/org/hibernate/test/event/collection/association/unidirectional/manytomany/UnidirectionalManyToManyBagMapping.hbm.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testsuite/src/test/java/org/hibernate/test/event/collection/association/unidirectional/onetomany/UnidirectionalOneToManyBagCollectionEventTest.java b/testsuite/src/test/java/org/hibernate/test/event/collection/association/unidirectional/onetomany/UnidirectionalOneToManyBagCollectionEventTest.java new file mode 100644 index 0000000000..edef9528ca --- /dev/null +++ b/testsuite/src/test/java/org/hibernate/test/event/collection/association/unidirectional/onetomany/UnidirectionalOneToManyBagCollectionEventTest.java @@ -0,0 +1,65 @@ +//$Id: $ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2007, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution statements + * applied by the authors. + * + * All third-party contributions are distributed under license by Red Hat + * Middleware LLC. This copyrighted material is made available to anyone + * wishing to use, modify, copy, or redistribute it subject to the terms + * and conditions of the GNU Lesser General Public License, as published by + * the Free Software Foundation. This program is distributed in the hope + * that it will be useful, but WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU Lesser General Public License for more details. You should + * have received a copy of the GNU Lesser General Public License along with + * this distribution; if not, write to: Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor Boston, MA 02110-1301 USA + */ +package org.hibernate.test.event.collection.association.unidirectional.onetomany; + +import java.util.ArrayList; +import java.util.Collection; + +import junit.framework.Test; + +import org.hibernate.junit.functional.FunctionalTestClassTestSuite; +import org.hibernate.test.event.collection.Child; +import org.hibernate.test.event.collection.ChildEntity; +import org.hibernate.test.event.collection.ParentWithCollection; +import org.hibernate.test.event.collection.association.AbstractAssociationCollectionEventTest; +import org.hibernate.test.event.collection.association.unidirectional.ParentWithCollectionOfEntities; + +/** + * + * @author Gail Badner + */ +public class UnidirectionalOneToManyBagCollectionEventTest extends AbstractAssociationCollectionEventTest { + + public UnidirectionalOneToManyBagCollectionEventTest(String string) { + super( string ); + } + + public static Test suite() { + return new FunctionalTestClassTestSuite( UnidirectionalOneToManyBagCollectionEventTest.class ); + } + + public String[] getMappings() { + return new String[] { "event/collection/association/unidirectional/onetomany/UnidirectionalOneToManyBagMapping.hbm.xml" }; + } + + public ParentWithCollection createParent(String name) { + return new ParentWithCollectionOfEntities( name ); + } + + public Collection createCollection() { + return new ArrayList(); + } + + public Child createChild(String name) { + return new ChildEntity( name ); + } +} diff --git a/testsuite/src/test/java/org/hibernate/test/event/collection/association/unidirectional/onetomany/UnidirectionalOneToManyBagMapping.hbm.xml b/testsuite/src/test/java/org/hibernate/test/event/collection/association/unidirectional/onetomany/UnidirectionalOneToManyBagMapping.hbm.xml new file mode 100644 index 0000000000..22c8977a10 --- /dev/null +++ b/testsuite/src/test/java/org/hibernate/test/event/collection/association/unidirectional/onetomany/UnidirectionalOneToManyBagMapping.hbm.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testsuite/src/test/java/org/hibernate/test/event/collection/association/unidirectional/onetomany/UnidirectionalOneToManySetCollectionEventTest.java b/testsuite/src/test/java/org/hibernate/test/event/collection/association/unidirectional/onetomany/UnidirectionalOneToManySetCollectionEventTest.java new file mode 100644 index 0000000000..fb2f671331 --- /dev/null +++ b/testsuite/src/test/java/org/hibernate/test/event/collection/association/unidirectional/onetomany/UnidirectionalOneToManySetCollectionEventTest.java @@ -0,0 +1,60 @@ +//$Id: $ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2007, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution statements + * applied by the authors. + * + * All third-party contributions are distributed under license by Red Hat + * Middleware LLC. This copyrighted material is made available to anyone + * wishing to use, modify, copy, or redistribute it subject to the terms + * and conditions of the GNU Lesser General Public License, as published by + * the Free Software Foundation. This program is distributed in the hope + * that it will be useful, but WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU Lesser General Public License for more details. You should + * have received a copy of the GNU Lesser General Public License along with + * this distribution; if not, write to: Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor Boston, MA 02110-1301 USA + */ +package org.hibernate.test.event.collection.association.unidirectional.onetomany; + +import java.util.Collection; +import java.util.HashSet; + +import junit.framework.Test; + +import org.hibernate.junit.functional.FunctionalTestClassTestSuite; +import org.hibernate.test.event.collection.ParentWithCollection; +import org.hibernate.test.event.collection.association.AbstractAssociationCollectionEventTest; +import org.hibernate.test.event.collection.association.unidirectional.ParentWithCollectionOfEntities; + +/** + * + * @author Gail Badner + */ +public class UnidirectionalOneToManySetCollectionEventTest extends AbstractAssociationCollectionEventTest { + + public UnidirectionalOneToManySetCollectionEventTest(String string) { + super( string ); + } + + public static Test suite() { + return new FunctionalTestClassTestSuite( UnidirectionalOneToManySetCollectionEventTest.class ); + } + + public String[] getMappings() { + return new String[] { "event/collection/association/unidirectional/onetomany/UnidirectionalOneToManySetMapping.hbm.xml" }; + } + + public ParentWithCollection createParent(String name) { + return new ParentWithCollectionOfEntities( name ); + } + + public Collection createCollection() { + return new HashSet(); + } +} + diff --git a/testsuite/src/test/java/org/hibernate/test/event/collection/association/unidirectional/onetomany/UnidirectionalOneToManySetMapping.hbm.xml b/testsuite/src/test/java/org/hibernate/test/event/collection/association/unidirectional/onetomany/UnidirectionalOneToManySetMapping.hbm.xml new file mode 100644 index 0000000000..e13ea2b05e --- /dev/null +++ b/testsuite/src/test/java/org/hibernate/test/event/collection/association/unidirectional/onetomany/UnidirectionalOneToManySetMapping.hbm.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testsuite/src/test/java/org/hibernate/test/event/collection/values/ParentWithCollectionOfValues.java b/testsuite/src/test/java/org/hibernate/test/event/collection/values/ParentWithCollectionOfValues.java new file mode 100644 index 0000000000..37225ef444 --- /dev/null +++ b/testsuite/src/test/java/org/hibernate/test/event/collection/values/ParentWithCollectionOfValues.java @@ -0,0 +1,45 @@ +//$Id: $ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2007, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution statements + * applied by the authors. + * + * All third-party contributions are distributed under license by Red Hat + * Middleware LLC. This copyrighted material is made available to anyone + * wishing to use, modify, copy, or redistribute it subject to the terms + * and conditions of the GNU Lesser General Public License, as published by + * the Free Software Foundation. This program is distributed in the hope + * that it will be useful, but WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU Lesser General Public License for more details. You should + * have received a copy of the GNU Lesser General Public License along with + * this distribution; if not, write to: Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor Boston, MA 02110-1301 USA + */ +package org.hibernate.test.event.collection.values; + +import java.util.Collection; + +import org.hibernate.test.event.collection.Child; +import org.hibernate.test.event.collection.ChildValue; +import org.hibernate.test.event.collection.AbstractParentWithCollection; + +/** + * + * @author Gail Badner + */ +public class ParentWithCollectionOfValues extends AbstractParentWithCollection { + public ParentWithCollectionOfValues() { + } + + public ParentWithCollectionOfValues(String name) { + super( name ); + } + + public Child createChild(String name) { + return new ChildValue( name ); + } +} \ No newline at end of file diff --git a/testsuite/src/test/java/org/hibernate/test/event/collection/values/ValuesBagCollectionEventTest.java b/testsuite/src/test/java/org/hibernate/test/event/collection/values/ValuesBagCollectionEventTest.java new file mode 100644 index 0000000000..a12de45825 --- /dev/null +++ b/testsuite/src/test/java/org/hibernate/test/event/collection/values/ValuesBagCollectionEventTest.java @@ -0,0 +1,59 @@ +//$Id: $ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2007, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution statements + * applied by the authors. + * + * All third-party contributions are distributed under license by Red Hat + * Middleware LLC. This copyrighted material is made available to anyone + * wishing to use, modify, copy, or redistribute it subject to the terms + * and conditions of the GNU Lesser General Public License, as published by + * the Free Software Foundation. This program is distributed in the hope + * that it will be useful, but WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU Lesser General Public License for more details. You should + * have received a copy of the GNU Lesser General Public License along with + * this distribution; if not, write to: Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor Boston, MA 02110-1301 USA + */ +package org.hibernate.test.event.collection.values; + +import java.util.ArrayList; +import java.util.Collection; + +import junit.framework.Test; + +import org.hibernate.junit.functional.FunctionalTestClassTestSuite; +import org.hibernate.test.event.collection.AbstractCollectionEventTest; +import org.hibernate.test.event.collection.ParentWithCollection; +import org.hibernate.test.event.collection.values.ParentWithCollectionOfValues; + +/** + * + * @author Gail Badner + */ +public class ValuesBagCollectionEventTest extends AbstractCollectionEventTest { + + public ValuesBagCollectionEventTest(String string) { + super( string ); + } + + public static Test suite() { + return new FunctionalTestClassTestSuite( ValuesBagCollectionEventTest.class ); + } + + public String[] getMappings() { + return new String[] { "event/collection/values/ValuesBagMapping.hbm.xml" }; + } + + public ParentWithCollection createParent(String name) { + return new ParentWithCollectionOfValues( name ); + } + + public Collection createCollection() { + return new ArrayList(); + } +} diff --git a/testsuite/src/test/java/org/hibernate/test/event/collection/values/ValuesBagMapping.hbm.xml b/testsuite/src/test/java/org/hibernate/test/event/collection/values/ValuesBagMapping.hbm.xml new file mode 100644 index 0000000000..5cea0d3c21 --- /dev/null +++ b/testsuite/src/test/java/org/hibernate/test/event/collection/values/ValuesBagMapping.hbm.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + +