[hibernate-commits] Hibernate SVN: r10948 - in trunk/Hibernate3: src/org/hibernate/event/def test/org/hibernate/test/propertyref/basic

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Thu Dec 7 16:53:17 EST 2006


Author: steve.ebersole at jboss.com
Date: 2006-12-07 16:53:10 -0500 (Thu, 07 Dec 2006)
New Revision: 10948

Modified:
   trunk/Hibernate3/src/org/hibernate/event/def/AbstractReassociateEventListener.java
   trunk/Hibernate3/src/org/hibernate/event/def/AbstractSaveEventListener.java
   trunk/Hibernate3/src/org/hibernate/event/def/DefaultDeleteEventListener.java
   trunk/Hibernate3/src/org/hibernate/event/def/DefaultReplicateEventListener.java
   trunk/Hibernate3/src/org/hibernate/event/def/DefaultSaveOrUpdateEventListener.java
   trunk/Hibernate3/src/org/hibernate/event/def/OnLockVisitor.java
   trunk/Hibernate3/src/org/hibernate/event/def/OnReplicateVisitor.java
   trunk/Hibernate3/src/org/hibernate/event/def/OnUpdateVisitor.java
   trunk/Hibernate3/src/org/hibernate/event/def/ReattachVisitor.java
   trunk/Hibernate3/test/org/hibernate/test/propertyref/basic/Person.hbm.xml
   trunk/Hibernate3/test/org/hibernate/test/propertyref/basic/PropertyRefTest.java
Log:
HHH-2291 - reattachment of collections with a property-ref key;
code and javadoc cleanup

Modified: trunk/Hibernate3/src/org/hibernate/event/def/AbstractReassociateEventListener.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/event/def/AbstractReassociateEventListener.java	2006-12-07 21:36:31 UTC (rev 10947)
+++ trunk/Hibernate3/src/org/hibernate/event/def/AbstractReassociateEventListener.java	2006-12-07 21:53:10 UTC (rev 10948)
@@ -5,7 +5,7 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.hibernate.HibernateException;
+
 import org.hibernate.LockMode;
 import org.hibernate.engine.EntityEntry;
 import org.hibernate.engine.EntityKey;
@@ -25,7 +25,7 @@
  */
 public class AbstractReassociateEventListener implements Serializable {
 
-	private static final Log log = LogFactory.getLog(AbstractReassociateEventListener.class);
+	private static final Log log = LogFactory.getLog( AbstractReassociateEventListener.class );
 
 	/**
 	 * Associates a given entity (either transient or associated with another session) to
@@ -35,52 +35,53 @@
 	 * @param object The entity to be associated
 	 * @param id The id of the entity.
 	 * @param persister The entity's persister instance.
+	 *
 	 * @return An EntityEntry representing the entity within this session.
-	 * @throws HibernateException
 	 */
-	protected final EntityEntry reassociate(AbstractEvent event, Object object, Serializable id, EntityPersister persister)
-	throws HibernateException {
-		
-		if ( log.isTraceEnabled() ) log.trace(
-				"reassociating transient instance: " +
-				MessageHelper.infoString( persister, id, event.getSession().getFactory() )
+	protected final EntityEntry reassociate(AbstractEvent event, Object object, Serializable id, EntityPersister persister) {
+
+		if ( log.isTraceEnabled() ) {
+			log.trace(
+					"reassociating transient instance: " +
+							MessageHelper.infoString( persister, id, event.getSession().getFactory() )
 			);
-		
+		}
+
 		EventSource source = event.getSession();
 		EntityKey key = new EntityKey( id, persister, source.getEntityMode() );
-		
-		source.getPersistenceContext().checkUniqueness(key, object);
-		
+
+		source.getPersistenceContext().checkUniqueness( key, object );
+
 		//get a snapshot
 		Object[] values = persister.getPropertyValues( object, source.getEntityMode() );
-		TypeFactory.deepCopy( 
-				values, 
-				persister.getPropertyTypes(), 
-				persister.getPropertyUpdateability(), 
-				values, 
-				source 
-			);
-		Object version = Versioning.getVersion(values, persister);
-		
+		TypeFactory.deepCopy(
+				values,
+				persister.getPropertyTypes(),
+				persister.getPropertyUpdateability(),
+				values,
+				source
+		);
+		Object version = Versioning.getVersion( values, persister );
+
 		EntityEntry newEntry = source.getPersistenceContext().addEntity(
-				object, 
-				Status.MANAGED, 
-				values, 
-				key, 
-				version, 
-				LockMode.NONE, 
-				true, 
-				persister, 
-				false, 
+				object,
+				Status.MANAGED,
+				values,
+				key,
+				version,
+				LockMode.NONE,
+				true,
+				persister,
+				false,
 				true //will be ignored, using the existing Entry instead
-			);
-		
-		new OnLockVisitor( source, id ).process( object, persister );
-		
+		);
+
+		new OnLockVisitor( source, id, object ).process( object, persister );
+
 		persister.afterReassociate( object, source );
-		
+
 		return newEntry;
-		
+
 	}
 
 }

Modified: trunk/Hibernate3/src/org/hibernate/event/def/AbstractSaveEventListener.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/event/def/AbstractSaveEventListener.java	2006-12-07 21:36:31 UTC (rev 10947)
+++ trunk/Hibernate3/src/org/hibernate/event/def/AbstractSaveEventListener.java	2006-12-07 21:53:10 UTC (rev 10948)
@@ -6,7 +6,7 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.hibernate.HibernateException;
+
 import org.hibernate.LockMode;
 import org.hibernate.NonUniqueObjectException;
 import org.hibernate.action.EntityIdentityInsertAction;
@@ -44,60 +44,59 @@
 	protected static final int DETACHED = 2;
 	protected static final int DELETED = 3;
 
-	private static final Log log = LogFactory.getLog(AbstractSaveEventListener.class);
+	private static final Log log = LogFactory.getLog( AbstractSaveEventListener.class );
 
 	/**
 	 * Prepares the save call using the given requested id.
+	 *
 	 * @param entity The entity to be saved.
 	 * @param requestedId The id to which to associate the entity.
+	 * @param entityName The name of the entity being saved.
+	 * @param anything Generally cascade-specific information.
 	 * @param source The session which is the source of this save event.
+	 *
 	 * @return The id used to save the entity.
-	 * @throws HibernateException
 	 */
 	protected Serializable saveWithRequestedId(
 			Object entity,
 			Serializable requestedId,
 			String entityName,
 			Object anything,
-			EventSource source) 
-	throws HibernateException {
+			EventSource source) {
 		return performSave(
 				entity,
 				requestedId,
-				source.getEntityPersister(entityName, entity),
+				source.getEntityPersister( entityName, entity ),
 				false,
 				anything,
 				source,
-		        true
-			);
+				true
+		);
 	}
 
 	/**
 	 * Prepares the save call using a newly generated id.
+	 *
 	 * @param entity The entity to be saved
 	 * @param entityName The entity-name for the entity to be saved
+	 * @param anything Generally cascade-specific information.
 	 * @param source The session which is the source of this save event.
 	 * @param requiresImmediateIdAccess does the event context require
 	 * access to the identifier immediately after execution of this method (if
 	 * not, post-insert style id generators may be postponed if we are outside
 	 * a transaction).
+	 *
 	 * @return The id used to save the entity; may be null depending on the
-	 * type of id generator used and the requiresImmediateIdAccess value
-	 * @throws HibernateException
+	 *         type of id generator used and the requiresImmediateIdAccess value
 	 */
 	protected Serializable saveWithGeneratedId(
 			Object entity,
 			String entityName,
 			Object anything,
 			EventSource source,
-	        boolean requiresImmediateIdAccess)
-	throws HibernateException {
-		
-		EntityPersister persister = source.getEntityPersister(entityName, entity);
-
-		Serializable generatedId = persister.getIdentifierGenerator()
-			.generate( source, entity );
-		
+			boolean requiresImmediateIdAccess) {
+		EntityPersister persister = source.getEntityPersister( entityName, entity );
+		Serializable generatedId = persister.getIdentifierGenerator().generate( source, entity );
 		if ( generatedId == null ) {
 			throw new IdentifierGenerationException( "null id generated for:" + entity.getClass() );
 		}
@@ -108,16 +107,17 @@
 			return performSave( entity, null, persister, true, anything, source, requiresImmediateIdAccess );
 		}
 		else {
-			
+
 			if ( log.isDebugEnabled() ) {
 				log.debug(
-						"generated identifier: " + 
-						persister.getIdentifierType().toLoggableString( generatedId, source.getFactory() ) + 
-						", using strategy: " + 
-						persister.getIdentifierGenerator().getClass().getName() //TODO: define toString()s for generators
-					);
+						"generated identifier: " +
+								persister.getIdentifierType().toLoggableString( generatedId, source.getFactory() ) +
+								", using strategy: " +
+								persister.getIdentifierGenerator().getClass().getName()
+						//TODO: define toString()s for generators
+				);
 			}
-			
+
 			return performSave( entity, generatedId, persister, false, anything, source, true );
 		}
 	}
@@ -125,18 +125,20 @@
 	/**
 	 * Ppepares the save call by checking the session caches for a pre-existing
 	 * entity and performing any lifecycle callbacks.
+	 *
 	 * @param entity The entity to be saved.
 	 * @param id The id by which to save the entity.
 	 * @param persister The entity's persister instance.
-	 * @param useIdentityColumn Is an identity column in use?
+	 * @param useIdentityColumn Is an identity column being used?
+	 * @param anything Generally cascade-specific information.
 	 * @param source The session from which the event originated.
 	 * @param requiresImmediateIdAccess does the event context require
 	 * access to the identifier immediately after execution of this method (if
 	 * not, post-insert style id generators may be postponed if we are outside
 	 * a transaction).
+	 *
 	 * @return The id used to save the entity; may be null depending on the
-	 * type of id generator used and the requiresImmediateIdAccess value
-	 * @throws HibernateException
+	 *         type of id generator used and the requiresImmediateIdAccess value
 	 */
 	protected Serializable performSave(
 			Object entity,
@@ -145,55 +147,54 @@
 			boolean useIdentityColumn,
 			Object anything,
 			EventSource source,
-	        boolean requiresImmediateIdAccess)
-	throws HibernateException {
+			boolean requiresImmediateIdAccess) {
 
 		if ( log.isTraceEnabled() ) {
-			log.trace( 
-					"saving " + 
-					MessageHelper.infoString( persister, id, source.getFactory() ) 
-				);
+			log.trace(
+					"saving " +
+							MessageHelper.infoString( persister, id, source.getFactory() )
+			);
 		}
-		
+
 		EntityKey key;
 		if ( !useIdentityColumn ) {
 			key = new EntityKey( id, persister, source.getEntityMode() );
-			Object old = source.getPersistenceContext().getEntity(key);
-			if (old != null) {
-				if ( source.getPersistenceContext().getEntry(old).getStatus() == Status.DELETED ) {
-					source.forceFlush( source.getPersistenceContext().getEntry(old) );
+			Object old = source.getPersistenceContext().getEntity( key );
+			if ( old != null ) {
+				if ( source.getPersistenceContext().getEntry( old ).getStatus() == Status.DELETED ) {
+					source.forceFlush( source.getPersistenceContext().getEntry( old ) );
 				}
 				else {
 					throw new NonUniqueObjectException( id, persister.getEntityName() );
 				}
 			}
-			persister.setIdentifier(entity, id, source.getEntityMode());
+			persister.setIdentifier( entity, id, source.getEntityMode() );
 		}
 		else {
 			key = null;
 		}
-		
-		if ( invokeSaveLifecycle(entity, persister, source) ) {
+
+		if ( invokeSaveLifecycle( entity, persister, source ) ) {
 			return id; //EARLY EXIT
 		}
 
 		return performSaveOrReplicate(
-				entity, 
-				key, 
-				persister, 
-				useIdentityColumn, 
-				anything, 
+				entity,
+				key,
+				persister,
+				useIdentityColumn,
+				anything,
 				source,
-		        requiresImmediateIdAccess
-			);
+				requiresImmediateIdAccess
+		);
 	}
-	
+
 	protected boolean invokeSaveLifecycle(Object entity, EntityPersister persister, EventSource source) {
 		// Sub-insertions should occur before containing insertion so
 		// Try to do the callback now
 		if ( persister.implementsLifecycle( source.getEntityMode() ) ) {
 			log.debug( "calling onSave()" );
-			if ( ( (Lifecycle) entity ).onSave(source) ) {
+			if ( ( ( Lifecycle ) entity ).onSave( source ) ) {
 				log.debug( "insertion vetoed by onSave()" );
 				return true;
 			}
@@ -203,21 +204,25 @@
 
 	protected void validate(Object entity, EntityPersister persister, EventSource source) {
 		if ( persister.implementsValidatable( source.getEntityMode() ) ) {
-            ( ( Validatable ) entity ).validate();
-        }
+			( ( Validatable ) entity ).validate();
+		}
 	}
 
 	/**
 	 * Performs all the actual work needed to save an entity (well to get the save moved to
 	 * the execution queue).
+	 *
 	 * @param entity The entity to be saved
 	 * @param key The id to be used for saving the entity (or null, in the case of identity columns)
 	 * @param persister The entity's persister instance.
 	 * @param useIdentityColumn Should an identity column be used for id generation?
+	 * @param anything Generally cascade-specific information.
 	 * @param source The session which is the source of the current event.
+	 * @param requiresImmediateIdAccess Is access to the identifier required immediately
+	 * after the completion of the save?  persist(), for example, does not require this...
+	 *
 	 * @return The id used to save the entity; may be null depending on the
-	 * type of id generator used and the requiresImmediateIdAccess value
-	 * @throws HibernateException
+	 *         type of id generator used and the requiresImmediateIdAccess value
 	 */
 	protected Serializable performSaveOrReplicate(
 			Object entity,
@@ -226,18 +231,17 @@
 			boolean useIdentityColumn,
 			Object anything,
 			EventSource source,
-	        boolean requiresImmediateIdAccess)
-	throws HibernateException {
-		
+			boolean requiresImmediateIdAccess) {
+
 		validate( entity, persister, source );
 
-		Serializable id = key==null ? null : key.getIdentifier();
+		Serializable id = key == null ? null : key.getIdentifier();
 
 		boolean inTxn = source.getJDBCContext().isTransactionInProgress();
 		boolean shouldDelayIdentityInserts = !inTxn && !requiresImmediateIdAccess;
 
 		if ( useIdentityColumn && !shouldDelayIdentityInserts ) {
-			log.trace("executing insertions");
+			log.trace( "executing insertions" );
 			source.getActionQueue().executeInserts();
 		}
 
@@ -253,46 +257,50 @@
 				null,
 				LockMode.WRITE,
 				useIdentityColumn,
-				persister, 
-				false, 
+				persister,
+				false,
 				false
-			);
+		);
 
-		cascadeBeforeSave(source, persister, entity, anything);
+		cascadeBeforeSave( source, persister, entity, anything );
 
-		Object[] values = persister.getPropertyValuesToInsert(entity, getMergeMap(anything), source);
+		Object[] values = persister.getPropertyValuesToInsert( entity, getMergeMap( anything ), source );
 		Type[] types = persister.getPropertyTypes();
 
-		boolean substitute = substituteValuesIfNecessary(entity, id, values, persister, source);
+		boolean substitute = substituteValuesIfNecessary( entity, id, values, persister, source );
 
 		if ( persister.hasCollections() ) {
-			substitute = substitute || visitCollectionsBeforeSave(id, values, types, source);
+			substitute = substitute || visitCollectionsBeforeSave( entity, id, values, types, source );
 		}
 
-		if (substitute) persister.setPropertyValues( entity, values, source.getEntityMode() );
+		if ( substitute ) {
+			persister.setPropertyValues( entity, values, source.getEntityMode() );
+		}
 
-		TypeFactory.deepCopy( 
-				values, 
-				types, 
-				persister.getPropertyUpdateability(), 
-				values, 
+		TypeFactory.deepCopy(
+				values,
+				types,
+				persister.getPropertyUpdateability(),
+				values,
 				source
+		);
+
+		new ForeignKeys.Nullifier( entity, false, useIdentityColumn, source )
+				.nullifyTransientReferences( values, types );
+		new Nullability( source ).checkNullability( values, persister, false );
+
+		if ( useIdentityColumn ) {
+			EntityIdentityInsertAction insert = new EntityIdentityInsertAction(
+					values, entity, persister, source, shouldDelayIdentityInserts
 			);
-		
-		new ForeignKeys.Nullifier(entity, false, useIdentityColumn, source)
-				.nullifyTransientReferences(values, types);
-		new Nullability(source).checkNullability( values, persister, false );
-		
-		if ( useIdentityColumn ) {
-			EntityIdentityInsertAction insert = new EntityIdentityInsertAction( values, entity, persister, source, shouldDelayIdentityInserts );
-			if ( ! shouldDelayIdentityInserts ) {
+			if ( !shouldDelayIdentityInserts ) {
 				log.debug( "executing identity-insert immediately" );
-				source.getActionQueue().execute(insert);
+				source.getActionQueue().execute( insert );
 				id = insert.getGeneratedId();
 				//now done in EntityIdentityInsertAction
 				//persister.setIdentifier( entity, id, source.getEntityMode() );
 				key = new EntityKey( id, persister, source.getEntityMode() );
-				source.getPersistenceContext().checkUniqueness(key, entity);
+				source.getPersistenceContext().checkUniqueness( key, entity );
 				//source.getBatcher().executeBatch(); //found another way to ensure that all batched joined inserts have been executed
 			}
 			else {
@@ -302,7 +310,7 @@
 			}
 		}
 
-		Object version = Versioning.getVersion(values, persister);
+		Object version = Versioning.getVersion( values, persister );
 		source.getPersistenceContext().addEntity(
 				entity,
 				Status.MANAGED,
@@ -312,18 +320,18 @@
 				LockMode.WRITE,
 				useIdentityColumn,
 				persister,
-				isVersionIncrementDisabled(), 
+				isVersionIncrementDisabled(),
 				false
-			);
+		);
 		//source.getPersistenceContext().removeNonExist( new EntityKey( id, persister, source.getEntityMode() ) );
 
 		if ( !useIdentityColumn ) {
-			source.getActionQueue().addAction( 
-					new EntityInsertAction(id, values, entity, version, persister, source) 
-				);
+			source.getActionQueue().addAction(
+					new EntityInsertAction( id, values, entity, version, persister, source )
+			);
 		}
 
-		cascadeAfterSave(source, persister, entity, anything);
+		cascadeAfterSave( source, persister, entity, anything );
 
 		markInterceptorDirty( entity, persister, source );
 
@@ -333,7 +341,7 @@
 	private void markInterceptorDirty(Object entity, EntityPersister persister, EventSource source) {
 		if ( FieldInterceptionHelper.isInstrumented( entity ) ) {
 			FieldInterceptor interceptor = FieldInterceptionHelper.injectFieldInterceptor(
-					entity, 
+					entity,
 					persister.getEntityName(),
 					null,
 					source
@@ -341,44 +349,55 @@
 			interceptor.dirty();
 		}
 	}
-	
+
 	protected Map getMergeMap(Object anything) {
 		return null;
 	}
-	
+
 	/**
 	 * After the save, will te version number be incremented
 	 * if the instance is modified?
+	 *
+	 * @return True if the version will be incremented on an entity change after save;
+	 *         false otherwise.
 	 */
 	protected boolean isVersionIncrementDisabled() {
 		return false;
 	}
-	
-	protected boolean visitCollectionsBeforeSave(Serializable id, Object[] values, Type[] types, EventSource source) {
-		WrapVisitor visitor = new WrapVisitor(source);
+
+	protected boolean visitCollectionsBeforeSave(Object entity, Serializable id, Object[] values, Type[] types, EventSource source) {
+		WrapVisitor visitor = new WrapVisitor( source );
 		// substitutes into values by side-effect
-		visitor.processEntityPropertyValues(values, types);
+		visitor.processEntityPropertyValues( values, types );
 		return visitor.isSubstitutionRequired();
 	}
-	
+
 	/**
 	 * Perform any property value substitution that is necessary
 	 * (interceptor callback, version initialization...)
+	 *
+	 * @param entity The entity
+	 * @param id The entity identifier
+	 * @param values The snapshot entity state
+	 * @param persister The entity persister
+	 * @param source The originating session
+	 *
+	 * @return True if the snapshot state changed such that
+	 * reinjection of the values into the entity is required.
 	 */
 	protected boolean substituteValuesIfNecessary(
-			Object entity, 
-			Serializable id, 
-			Object[] values, 
+			Object entity,
+			Serializable id,
+			Object[] values,
 			EntityPersister persister,
-			SessionImplementor source
-	) {
+			SessionImplementor source) {
 		boolean substitute = source.getInterceptor().onSave(
 				entity,
 				id,
 				values,
 				persister.getPropertyNames(),
 				persister.getPropertyTypes()
-			);
+		);
 
 		//keep the existing version number in the case of replicate!
 		if ( persister.isVersioned() ) {
@@ -386,7 +405,7 @@
 					values,
 					persister.getVersionProperty(),
 					persister.getVersionType(),
-			        source
+					source
 			) || substitute;
 		}
 		return substitute;
@@ -394,23 +413,23 @@
 
 	/**
 	 * Handles the calls needed to perform pre-save cascades for the given entity.
+	 *
 	 * @param source The session from whcih the save event originated.
 	 * @param persister The entity's persister instance.
 	 * @param entity The entity to be saved.
-	 * @throws HibernateException
+	 * @param anything Generally cascade-specific data
 	 */
 	protected void cascadeBeforeSave(
 			EventSource source,
 			EntityPersister persister,
 			Object entity,
-			Object anything)
-	throws HibernateException {
+			Object anything) {
 
 		// cascade-save to many-to-one BEFORE the parent is saved
 		source.getPersistenceContext().incrementCascadeLevel();
 		try {
 			new Cascade( getCascadeAction(), Cascade.BEFORE_INSERT_AFTER_DELETE, source )
-					.cascade(persister, entity,	anything);
+					.cascade( persister, entity, anything );
 		}
 		finally {
 			source.getPersistenceContext().decrementCascadeLevel();
@@ -419,96 +438,105 @@
 
 	/**
 	 * Handles to calls needed to perform post-save cascades.
+	 *
 	 * @param source The session from which the event originated.
 	 * @param persister The entity's persister instance.
 	 * @param entity The entity beng saved.
-	 * @throws HibernateException
+	 * @param anything Generally cascade-specific data
 	 */
 	protected void cascadeAfterSave(
 			EventSource source,
-	        EntityPersister persister,
-	        Object entity,
-			Object anything)
-	throws HibernateException {
+			EntityPersister persister,
+			Object entity,
+			Object anything) {
 
 		// cascade-save to collections AFTER the collection owner was saved
 		source.getPersistenceContext().incrementCascadeLevel();
 		try {
 			new Cascade( getCascadeAction(), Cascade.AFTER_INSERT_BEFORE_DELETE, source )
-					.cascade(persister, entity,	anything);
+					.cascade( persister, entity, anything );
 		}
 		finally {
 			source.getPersistenceContext().decrementCascadeLevel();
 		}
 	}
-	
+
 	protected abstract CascadingAction getCascadeAction();
-	
+
 	/**
 	 * Determine whether the entity is persistent, detached, or transient
+	 *
+	 * @param entity The entity to check
+	 * @param entityName The name of the entity
+	 * @param entry The entity's entry in the persistence context
+	 * @param source The originating session.
+	 *
+	 * @return The state.
 	 */
 	protected int getEntityState(
-			Object entity, 
-			String entityName, 
+			Object entity,
+			String entityName,
 			EntityEntry entry, //pass this as an argument only to avoid double looking
 			SessionImplementor source) {
 
-		if ( entry != null ) {
-			 // the object is persistent as it has an entry associated with the
-			// session; so check its status
+		if ( entry != null ) { // the object is persistent
+
+			//the entity is associated with the session, so check its status
 			if ( entry.getStatus() != Status.DELETED ) {
 				// do nothing for persistent instances
 				if ( log.isTraceEnabled() ) {
-					log.trace( 
-							"persistent instance of: " + 
-							getLoggableName(entityName, entity) 
-						);
+					log.trace(
+							"persistent instance of: " +
+									getLoggableName( entityName, entity )
+					);
 				}
 				return PERSISTENT;
 			}
-			else { 
+			else {
 				//ie. e.status==DELETED
 				if ( log.isTraceEnabled() ) {
-					log.trace( 
-							"deleted instance of: " + 
-							getLoggableName(entityName, entity) 
-						);
+					log.trace(
+							"deleted instance of: " +
+									getLoggableName( entityName, entity )
+					);
 				}
 				return DELETED;
 			}
-			
+
 		}
-		else {
-			// the entity is not associated with the session, so the various
-			// unsaved-value algorithms to determine whether it is transient
-			// or detached
+		else { // the object is transient or detached
+
+			//the entity is not associated with the session, so
+			//try interceptor and unsaved-value
+
 			if ( ForeignKeys.isTransient( entityName, entity, getAssumedUnsaved(), source ) ) {
 				if ( log.isTraceEnabled() ) {
-					log.trace( 
-							"transient instance of: " + 
-							getLoggableName(entityName, entity) 
-						);
+					log.trace(
+							"transient instance of: " +
+									getLoggableName( entityName, entity )
+					);
 				}
 				return TRANSIENT;
 			}
 			else {
 				if ( log.isTraceEnabled() ) {
-					log.trace( 
-							"detached instance of: " + 
-							getLoggableName(entityName, entity) 
-						);
+					log.trace(
+							"detached instance of: " +
+									getLoggableName( entityName, entity )
+					);
 				}
 				return DETACHED;
 			}
 
 		}
 	}
-	
+
 	protected String getLoggableName(String entityName, Object entity) {
-		return entityName==null ? entity.getClass().getName() : entityName;
+		return entityName == null ? entity.getClass().getName() : entityName;
 	}
-	
+
 	protected Boolean getAssumedUnsaved() {
 		return null;
 	}
+
 }

Modified: trunk/Hibernate3/src/org/hibernate/event/def/DefaultDeleteEventListener.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/event/def/DefaultDeleteEventListener.java	2006-12-07 21:36:31 UTC (rev 10947)
+++ trunk/Hibernate3/src/org/hibernate/event/def/DefaultDeleteEventListener.java	2006-12-07 21:53:10 UTC (rev 10948)
@@ -6,6 +6,7 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+
 import org.hibernate.CacheMode;
 import org.hibernate.HibernateException;
 import org.hibernate.LockMode;
@@ -38,17 +39,27 @@
  */
 public class DefaultDeleteEventListener implements DeleteEventListener {
 
-	private static final Log log = LogFactory.getLog(DefaultDeleteEventListener.class);
+	private static final Log log = LogFactory.getLog( DefaultDeleteEventListener.class );
 
-    /** Handle the given delete event.
-     *
-     * @param event The delete event to be handled.
-     * @throws HibernateException
-     */
+	/**
+	 * Handle the given delete event.
+	 *
+	 * @param event The delete event to be handled.
+	 *
+	 * @throws HibernateException
+	 */
 	public void onDelete(DeleteEvent event) throws HibernateException {
 		onDelete( event, new IdentitySet() );
 	}
 
+	/**
+	 * Handle the given delete event.  This is the cascaded form.
+	 *
+	 * @param event The delete event.
+	 * @param transientEntities The cache of entities already deleted
+	 *
+	 * @throws HibernateException
+	 */
 	public void onDelete(DeleteEvent event, Set transientEntities) throws HibernateException {
 
 		final EventSource source = event.getSession();
@@ -79,15 +90,15 @@
 
 			if ( id == null ) {
 				throw new TransientObjectException(
-					"the detached instance passed to delete() had a null identifier"
+						"the detached instance passed to delete() had a null identifier"
 				);
 			}
 
 			EntityKey key = new EntityKey( id, persister, source.getEntityMode() );
 
-			persistenceContext.checkUniqueness(key, entity);
+			persistenceContext.checkUniqueness( key, entity );
 
-			new OnUpdateVisitor( source, id ).process( entity, persister );
+			new OnUpdateVisitor( source, id, entity ).process( entity, persister );
 
 			version = persister.getVersion( entity, source.getEntityMode() );
 
@@ -102,7 +113,7 @@
 					persister,
 					false,
 					false
-				);
+			);
 		}
 		else {
 			log.trace( "deleting a persistent instance" );
@@ -123,7 +134,9 @@
 				);
 		}*/
 
-		if ( invokeDeleteLifecycle( source, entity, persister ) ) return;
+		if ( invokeDeleteLifecycle( source, entity, persister ) ) {
+			return;
+		}
 
 		deleteEntity( source, entity, entityEntry, event.isCascadeDeleteEnabled(), persister, transientEntities );
 
@@ -132,6 +145,14 @@
 		}
 	}
 
+	/**
+	 * Called when we have recognized an attempt to delete a detached entity.
+	 * <p/>
+	 * This is perfectly valid in Hibernate usage; JPA, however, forbids this.
+	 * Thus, this is a hook for HEM to affect this behavior.
+	 *
+	 * @param event The event.
+	 */
 	protected void performDetachedEntityDeletionCheck(DeleteEvent event) {
 		// ok in normal Hibernate usage to delete a detached entity; JPA however
 		// forbids it, thus this is a hook for HEM to affect this behavior
@@ -168,19 +189,31 @@
 		cascadeAfterDelete( session, persister, entity, transientEntities );
 	}
 
+	/**
+	 * Perform the entity deletion.  Well, as with most operations, does not
+	 * really perform it; just schedules an action/execution with the
+	 * {@link org.hibernate.engine.ActionQueue} for execution during flush.
+	 *
+	 * @param session The originating session
+	 * @param entity The entity to delete
+	 * @param entityEntry The entity's entry in the {@link PersistenceContext}
+	 * @param isCascadeDeleteEnabled Is delete cascading enabled?
+	 * @param persister The entity persister.
+	 * @param transientEntities A cache of already deleted entities.
+	 */
 	protected final void deleteEntity(
-		final EventSource session,
-		final Object entity,
-		final EntityEntry entityEntry,
-		final boolean isCascadeDeleteEnabled,
-		final EntityPersister persister,
-		final Set transientEntities) throws HibernateException {
+			final EventSource session,
+			final Object entity,
+			final EntityEntry entityEntry,
+			final boolean isCascadeDeleteEnabled,
+			final EntityPersister persister,
+			final Set transientEntities) {
 
 		if ( log.isTraceEnabled() ) {
 			log.trace(
 					"deleting " +
-					MessageHelper.infoString( persister, entityEntry.getId(), session.getFactory() )
-				);
+							MessageHelper.infoString( persister, entityEntry.getId(), session.getFactory() )
+			);
 		}
 
 		final PersistenceContext persistenceContext = session.getPersistenceContext();
@@ -196,7 +229,7 @@
 		}
 
 		final Object[] deletedState = createDeletedState( persister, currentState, session );
-		entityEntry.setDeletedState(deletedState);
+		entityEntry.setDeletedState( deletedState );
 
 		session.getInterceptor().onDelete(
 				entity,
@@ -207,15 +240,15 @@
 		);
 
 		// before any callbacks, etc, so subdeletions see that this deletion happened first
-		persistenceContext.setEntryStatus(entityEntry, Status.DELETED);
-		EntityKey key = new EntityKey( entityEntry.getId(), persister, session.getEntityMode()  );
+		persistenceContext.setEntryStatus( entityEntry, Status.DELETED );
+		EntityKey key = new EntityKey( entityEntry.getId(), persister, session.getEntityMode() );
 
 		cascadeBeforeDelete( session, persister, entity, entityEntry, transientEntities );
 
-		new ForeignKeys.Nullifier(entity, true, false, session)
+		new ForeignKeys.Nullifier( entity, true, false, session )
 				.nullifyTransientReferences( entityEntry.getDeletedState(), propTypes );
-		new Nullability(session).checkNullability( entityEntry.getDeletedState(), persister, true );
-		persistenceContext.getNullifiableEntityKeys().add(key);
+		new Nullability( session ).checkNullability( entityEntry.getDeletedState(), persister, true );
+		persistenceContext.getNullifiableEntityKeys().add( key );
 
 		// Ensures that containing deletions happen before sub-deletions
 		session.getActionQueue().addAction(
@@ -251,8 +284,8 @@
 	protected boolean invokeDeleteLifecycle(EventSource session, Object entity, EntityPersister persister) {
 		if ( persister.implementsLifecycle( session.getEntityMode() ) ) {
 			log.debug( "calling onDelete()" );
-			if ( ( (Lifecycle) entity ).onDelete(session) ) {
-				log.debug("deletion vetoed by onDelete()");
+			if ( ( ( Lifecycle ) entity ).onDelete( session ) ) {
+				log.debug( "deletion vetoed by onDelete()" );
 				return true;
 			}
 		}
@@ -261,13 +294,13 @@
 
 	protected void cascadeBeforeDelete(
 			EventSource session,
-	        EntityPersister persister,
-	        Object entity,
-	        EntityEntry entityEntry,
-	        Set transientEntities) throws HibernateException {
+			EntityPersister persister,
+			Object entity,
+			EntityEntry entityEntry,
+			Set transientEntities) throws HibernateException {
 
 		CacheMode cacheMode = session.getCacheMode();
-		session.setCacheMode(CacheMode.GET);
+		session.setCacheMode( CacheMode.GET );
 		session.getPersistenceContext().incrementCascadeLevel();
 		try {
 			// cascade-delete to collections BEFORE the collection owner is deleted
@@ -276,18 +309,18 @@
 		}
 		finally {
 			session.getPersistenceContext().decrementCascadeLevel();
-			session.setCacheMode(cacheMode);
+			session.setCacheMode( cacheMode );
 		}
 	}
 
 	protected void cascadeAfterDelete(
 			EventSource session,
-	        EntityPersister persister,
-	        Object entity,
-	        Set transientEntities) throws HibernateException {
+			EntityPersister persister,
+			Object entity,
+			Set transientEntities) throws HibernateException {
 
 		CacheMode cacheMode = session.getCacheMode();
-		session.setCacheMode(CacheMode.GET);
+		session.setCacheMode( CacheMode.GET );
 		session.getPersistenceContext().incrementCascadeLevel();
 		try {
 			// cascade-delete to many-to-one AFTER the parent was deleted
@@ -296,7 +329,7 @@
 		}
 		finally {
 			session.getPersistenceContext().decrementCascadeLevel();
-			session.setCacheMode(cacheMode);
+			session.setCacheMode( cacheMode );
 		}
 	}
 

Modified: trunk/Hibernate3/src/org/hibernate/event/def/DefaultReplicateEventListener.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/event/def/DefaultReplicateEventListener.java	2006-12-07 21:36:31 UTC (rev 10947)
+++ trunk/Hibernate3/src/org/hibernate/event/def/DefaultReplicateEventListener.java	2006-12-07 21:53:10 UTC (rev 10948)
@@ -30,44 +30,43 @@
  */
 public class DefaultReplicateEventListener extends AbstractSaveEventListener implements ReplicateEventListener {
 
-	private static final Log log = LogFactory.getLog(DefaultReplicateEventListener.class);
+	private static final Log log = LogFactory.getLog( DefaultReplicateEventListener.class );
 
-	/** 
+	/**
 	 * Handle the given replicate event.
 	 *
 	 * @param event The replicate event to be handled.
-	 * @throws HibernateException
+	 *
+	 * @throws TransientObjectException An invalid attempt to replicate a transient entity.
 	 */
-	public void onReplicate(ReplicateEvent event) throws HibernateException {
-
+	public void onReplicate(ReplicateEvent event) {
 		final EventSource source = event.getSession();
-		
 		if ( source.getPersistenceContext().reassociateIfUninitializedProxy( event.getObject() ) ) {
-			log.trace("uninitialized proxy passed to replicate()");
+			log.trace( "uninitialized proxy passed to replicate()" );
 			return;
 		}
 
 		Object entity = source.getPersistenceContext().unproxyAndReassociate( event.getObject() );
 
-		if ( source.getPersistenceContext().isEntryFor(entity) ) {
-			log.trace("ignoring persistent instance passed to replicate()");
+		if ( source.getPersistenceContext().isEntryFor( entity ) ) {
+			log.trace( "ignoring persistent instance passed to replicate()" );
 			//hum ... should we cascade anyway? throw an exception? fine like it is?
 			return;
 		}
 
 		EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity );
-		
+
 		// get the id from the object
 		/*if ( persister.isUnsaved(entity, source) ) {
 			throw new TransientObjectException("transient instance passed to replicate()");
 		}*/
 		Serializable id = persister.getIdentifier( entity, source.getEntityMode() );
-		if (id==null) {
-			throw new TransientObjectException("instance with null id passed to replicate()");
+		if ( id == null ) {
+			throw new TransientObjectException( "instance with null id passed to replicate()" );
 		}
 
 		final ReplicationMode replicationMode = event.getReplicationMode();
-		
+
 		final Object oldVersion;
 		if ( replicationMode == ReplicationMode.EXCEPTION ) {
 			//always do an INSERT, and let it fail by constraint violation
@@ -75,14 +74,16 @@
 		}
 		else {
 			//what is the version on the database?
-			oldVersion = persister.getCurrentVersion(id, source);
+			oldVersion = persister.getCurrentVersion( id, source );
 		}
 
-		if ( oldVersion!=null ) {
+		if ( oldVersion != null ) {
 			//existing row - do an update if appropriate
 			if ( log.isTraceEnabled() ) {
-				log.trace( "found existing row for " + 
-					MessageHelper.infoString( persister, id, source.getFactory() ) );
+				log.trace(
+						"found existing row for " +
+								MessageHelper.infoString( persister, id, source.getFactory() )
+				);
 			}
 
 			boolean canReplicate = replicationMode.shouldOverwriteCurrentVersion(
@@ -92,26 +93,28 @@
 					persister.getVersionType()
 			);
 
-			if (canReplicate) {
+			if ( canReplicate ) {
 				//will result in a SQL UPDATE:
-				performReplication(entity, id, oldVersion, persister, replicationMode, source);
+				performReplication( entity, id, oldVersion, persister, replicationMode, source );
 			}
 			else {
 				//else do nothing (don't even reassociate object!)
-				log.trace("no need to replicate");
+				log.trace( "no need to replicate" );
 			}
-			
+
 			//TODO: would it be better to do a refresh from db?
 		}
 		else {
 			// no existing row - do an insert
 			if ( log.isTraceEnabled() ) {
-				log.trace( "no existing row, replicating new instance " + 
-					MessageHelper.infoString( persister, id, source.getFactory() ) );
+				log.trace(
+						"no existing row, replicating new instance " +
+								MessageHelper.infoString( persister, id, source.getFactory() )
+				);
 			}
 
 			final boolean regenerate = persister.isIdentifierAssignedByInsert(); // prefer re-generation of identity!
-			final EntityKey key = regenerate ? 
+			final EntityKey key = regenerate ?
 					null : new EntityKey( id, persister, source.getEntityMode() );
 
 			performSaveOrReplicate(
@@ -121,77 +124,74 @@
 					regenerate,
 					replicationMode,
 					source,
-			        true
+					true
 			);
 
 		}
 	}
 
-	protected boolean visitCollectionsBeforeSave(Serializable id, Object[] values, Type[] types, EventSource source) {
+	protected boolean visitCollectionsBeforeSave(Object entity, Serializable id, Object[] values, Type[] types, EventSource source) {
 		//TODO: we use two visitors here, inefficient!
-		OnReplicateVisitor visitor = new OnReplicateVisitor(source, id, false);
-		visitor.processEntityPropertyValues(values, types);
-		return super.visitCollectionsBeforeSave(id, values, types, source);
+		OnReplicateVisitor visitor = new OnReplicateVisitor( source, id, entity, false );
+		visitor.processEntityPropertyValues( values, types );
+		return super.visitCollectionsBeforeSave( entity, id, values, types, source );
 	}
 
 	protected boolean substituteValuesIfNecessary(
-			Object entity, 
-			Serializable id, 
-			Object[] values, 
+			Object entity,
+			Serializable id,
+			Object[] values,
 			EntityPersister persister,
-			SessionImplementor source
-	) {
+			SessionImplementor source) {
 		return false;
 	}
-	
+
 	protected boolean isVersionIncrementDisabled() {
 		return true;
 	}
-	
-	private final void performReplication(
+
+	private void performReplication(
 			Object entity,
 			Serializable id,
 			Object version,
 			EntityPersister persister,
 			ReplicationMode replicationMode,
-			EventSource source) 
-	throws HibernateException {
+			EventSource source) throws HibernateException {
 
 		if ( log.isTraceEnabled() ) {
-			log.trace( 
-				"replicating changes to " + 
-				MessageHelper.infoString( persister, id, source.getFactory() ) 
+			log.trace(
+					"replicating changes to " +
+							MessageHelper.infoString( persister, id, source.getFactory() )
 			);
 		}
 
-		new OnReplicateVisitor(source, id, true).process( entity, persister );
+		new OnReplicateVisitor( source, id, entity, true ).process( entity, persister );
 
-		source.getPersistenceContext().addEntity( 
-				entity, 
-				Status.MANAGED, 
-				null, 
-				new EntityKey( id, persister, source.getEntityMode() ), 
-				version, 
-				LockMode.NONE, 
-				true, 
-				persister, 
-				true, 
+		source.getPersistenceContext().addEntity(
+				entity,
+				Status.MANAGED,
+				null,
+				new EntityKey( id, persister, source.getEntityMode() ),
+				version,
+				LockMode.NONE,
+				true,
+				persister,
+				true,
 				false
-			);
+		);
 
 		cascadeAfterReplicate( entity, persister, replicationMode, source );
 	}
 
 	private void cascadeAfterReplicate(
-			Object entity, 
-			EntityPersister persister, 
-			ReplicationMode replicationMode, 
-			EventSource source
-	) {
+			Object entity,
+			EntityPersister persister,
+			ReplicationMode replicationMode,
+			EventSource source) {
 		source.getPersistenceContext().incrementCascadeLevel();
 		try {
-			new Cascade(CascadingAction.REPLICATE, Cascade.AFTER_UPDATE, source)
-					.cascade(persister, entity, replicationMode);
+			new Cascade( CascadingAction.REPLICATE, Cascade.AFTER_UPDATE, source )
+					.cascade( persister, entity, replicationMode );
 		}
 		finally {
 			source.getPersistenceContext().decrementCascadeLevel();

Modified: trunk/Hibernate3/src/org/hibernate/event/def/DefaultSaveOrUpdateEventListener.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/event/def/DefaultSaveOrUpdateEventListener.java	2006-12-07 21:36:31 UTC (rev 10947)
+++ trunk/Hibernate3/src/org/hibernate/event/def/DefaultSaveOrUpdateEventListener.java	2006-12-07 21:53:10 UTC (rev 10948)
@@ -5,6 +5,7 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+
 import org.hibernate.AssertionFailure;
 import org.hibernate.EntityMode;
 import org.hibernate.HibernateException;
@@ -27,218 +28,240 @@
 import org.hibernate.proxy.HibernateProxy;
 
 /**
- * Defines the default update event listener used by hibernate for updating
- * transient entities in response to generated update events.
+ * Defines the default listener used by Hibernate for handling save-update
+ * events.
  *
- * @author Steve Ebersole, Gavin King
+ * @author Steve Ebersole
+ * @author Gavin King
  */
 public class DefaultSaveOrUpdateEventListener extends AbstractSaveEventListener implements SaveOrUpdateEventListener {
 
-	private static final Log log = LogFactory.getLog(DefaultSaveOrUpdateEventListener.class);
+	private static final Log log = LogFactory.getLog( DefaultSaveOrUpdateEventListener.class );
 
-	/** 
+	/**
 	 * Handle the given update event.
 	 *
 	 * @param event The update event to be handled.
-	 * @throws HibernateException
 	 */
-	public void onSaveOrUpdate(SaveOrUpdateEvent event) throws HibernateException {
-		
+	public void onSaveOrUpdate(SaveOrUpdateEvent event) {
 		final SessionImplementor source = event.getSession();
 		final Object object = event.getObject();
+		final Serializable requestedId = event.getRequestedId();
 
-		final Serializable requestedId = event.getRequestedId();
-		if ( requestedId!=null ) {
-			//assign the requested id to the proxy, *before* 
+		if ( requestedId != null ) {
+			//assign the requested id to the proxy, *before*
 			//reassociating the proxy
 			if ( object instanceof HibernateProxy ) {
-				( (HibernateProxy) object ).getHibernateLazyInitializer().setIdentifier(requestedId);
+				( ( HibernateProxy ) object ).getHibernateLazyInitializer().setIdentifier( requestedId );
 			}
 		}
-		
-		if ( reassociateIfUninitializedProxy(object, source) ) {
-			log.trace("reassociated uninitialized proxy");
-			// an uninitialized proxy, noop, don't even need to 
+
+		if ( reassociateIfUninitializedProxy( object, source ) ) {
+			log.trace( "reassociated uninitialized proxy" );
+			// an uninitialized proxy, noop, don't even need to
 			// return an id, since it is never a save()
 		}
 		else {
 			//initialize properties of the event:
-			final Object entity = source.getPersistenceContext().unproxyAndReassociate(object);
-			event.setEntity(entity);
-			event.setEntry( source.getPersistenceContext().getEntry(entity) );
+			final Object entity = source.getPersistenceContext().unproxyAndReassociate( object );
+			event.setEntity( entity );
+			event.setEntry( source.getPersistenceContext().getEntry( entity ) );
 			//return the id in the event object
-			event.setResultId( performSaveOrUpdate(event) );
+			event.setResultId( performSaveOrUpdate( event ) );
 		}
-		
+
 	}
-	
+
 	protected boolean reassociateIfUninitializedProxy(Object object, SessionImplementor source) {
-		return source.getPersistenceContext().reassociateIfUninitializedProxy(object);
+		return source.getPersistenceContext().reassociateIfUninitializedProxy( object );
 	}
-	
+
 	protected Serializable performSaveOrUpdate(SaveOrUpdateEvent event) {
-		
-		// use various roles to determine if the instance is 
-		// transient, persistent or detached:
-		
-		int entityState = getEntityState( 
-				event.getEntity(), 
-				event.getEntityName(), 
-				event.getEntry(), 
-				event.getSession() 
-			);
-		
-		switch (entityState) {
-			case DETACHED: 
-				entityIsDetached(event); 
+		int entityState = getEntityState(
+				event.getEntity(),
+				event.getEntityName(),
+				event.getEntry(),
+				event.getSession()
+		);
+
+		switch ( entityState ) {
+			case DETACHED:
+				entityIsDetached( event );
 				return null;
 			case PERSISTENT:
-				return entityIsPersistent(event);
+				return entityIsPersistent( event );
 			default: //TRANSIENT or DELETED
-				return entityIsTransient(event);	
+				return entityIsTransient( event );
 		}
-		
 	}
-	
+
 	protected Serializable entityIsPersistent(SaveOrUpdateEvent event) throws HibernateException {
-		
-		log.trace("ignoring persistent instance");
-		
+		log.trace( "ignoring persistent instance" );
+
 		EntityEntry entityEntry = event.getEntry();
-		if ( entityEntry==null ) {
-			throw new AssertionFailure("entity was transient or detached");
+		if ( entityEntry == null ) {
+			throw new AssertionFailure( "entity was transient or detached" );
 		}
 		else {
-			
+
 			if ( entityEntry.getStatus() == Status.DELETED ) {
-				throw new AssertionFailure("entity was deleted");
+				throw new AssertionFailure( "entity was deleted" );
 			}
-			
+
 			final SessionFactoryImplementor factory = event.getSession().getFactory();
 
 			Serializable requestedId = event.getRequestedId();
-			
+
 			Serializable savedId;
 			if ( requestedId == null ) {
 				savedId = entityEntry.getId();
 			}
 			else {
-				
+
 				final boolean isEqual = !entityEntry.getPersister().getIdentifierType()
 						.isEqual( requestedId, entityEntry.getId(), event.getSession().getEntityMode(), factory );
-				
+
 				if ( isEqual ) {
 					throw new PersistentObjectException(
 							"object passed to save() was already persistent: " +
-							MessageHelper.infoString( entityEntry.getPersister(), requestedId, factory )
-						);
+									MessageHelper.infoString( entityEntry.getPersister(), requestedId, factory )
+					);
 				}
-				
+
 				savedId = requestedId;
-				
+
 			}
-			
+
 			if ( log.isTraceEnabled() ) {
-				log.trace( 
-						"object already associated with session: " + 
-						MessageHelper.infoString( entityEntry.getPersister(), savedId, factory )
-					);
+				log.trace(
+						"object already associated with session: " +
+								MessageHelper.infoString( entityEntry.getPersister(), savedId, factory )
+				);
 			}
-			
+
 			return savedId;
-			
+
 		}
 	}
-		
-	/** 
-	 * Handle the given save event.
+
+	/**
+	 * The given save-update event named a transient entity.
+	 * <p/>
+	 * Here, we will perform the save processing.
 	 *
 	 * @param event The save event to be handled.
-	 * @throws HibernateException
+	 *
+	 * @return The entity's identifier after saving.
 	 */
-	protected Serializable entityIsTransient(SaveOrUpdateEvent event) throws HibernateException {
-		
-		log.trace("saving transient instance");
+	protected Serializable entityIsTransient(SaveOrUpdateEvent event) {
 
-		final EventSource source = event.getSession();		
+		log.trace( "saving transient instance" );
 
+		final EventSource source = event.getSession();
+
 		EntityEntry entityEntry = event.getEntry();
 		if ( entityEntry != null ) {
 			if ( entityEntry.getStatus() == Status.DELETED ) {
-				source.forceFlush(entityEntry);
+				source.forceFlush( entityEntry );
 			}
 			else {
-				throw new AssertionFailure("entity was persistent");
+				throw new AssertionFailure( "entity was persistent" );
 			}
 		}
-		
-		Serializable id = saveWithGeneratedOrRequestedId(event);
 
+		Serializable id = saveWithGeneratedOrRequestedId( event );
+
 		source.getPersistenceContext().reassociateProxy( event.getObject(), id );
-		
+
 		return id;
 	}
-	
+
 	/**
 	 * Save the transient instance, assigning the right identifier
+	 *
+	 * @param event The initiating event.
+	 *
+	 * @return The entity's identifier value after saving.
 	 */
 	protected Serializable saveWithGeneratedOrRequestedId(SaveOrUpdateEvent event) {
 		return saveWithGeneratedId(
-				event.getEntity(), 
-				event.getEntityName(), 
-				null, 
+				event.getEntity(),
+				event.getEntityName(),
+				null,
 				event.getSession(),
-		        true
+				true
 		);
 	}
-	
-	/** 
-	 * Handle the given update event.
+
+	/**
+	 * The given save-update event named a detached entity.
+	 * <p/>
+	 * Here, we will perform the update processing.
 	 *
 	 * @param event The update event to be handled.
-	 * @throws HibernateException
 	 */
-	protected void entityIsDetached(SaveOrUpdateEvent event) throws HibernateException {
-		
-		log.trace("updating detached instance");
-				
-		
-		if ( event.getSession().getPersistenceContext().isEntryFor( event.getEntity() ) ) { 
+	protected void entityIsDetached(SaveOrUpdateEvent event) {
+
+		log.trace( "updating detached instance" );
+
+
+		if ( event.getSession().getPersistenceContext().isEntryFor( event.getEntity() ) ) {
 			//TODO: assertion only, could be optimized away
-			throw new AssertionFailure("entity was persistent");
+			throw new AssertionFailure( "entity was persistent" );
 		}
-		
+
 		Object entity = event.getEntity();
 
 		EntityPersister persister = event.getSession().getEntityPersister( event.getEntityName(), entity );
 
-		event.setRequestedId( getUpdateId( entity, persister, event.getRequestedId(), event.getSession().getEntityMode() ) );
-		
-		performUpdate(event, entity, persister);
+		event.setRequestedId(
+				getUpdateId(
+						entity, persister, event.getRequestedId(), event.getSession().getEntityMode()
+				)
+		);
 
+		performUpdate( event, entity, persister );
+
 	}
-	
-	protected Serializable getUpdateId(Object entity, EntityPersister persister, Serializable requestedId, EntityMode entityMode)
-	throws HibernateException {
+
+	/**
+	 * Determine the id to use for updating.
+	 *
+	 * @param entity The entity.
+	 * @param persister The entity persister
+	 * @param requestedId The requested identifier
+	 * @param entityMode The entity mode.
+	 *
+	 * @return The id.
+	 *
+	 * @throws TransientObjectException If the entity is considered transient.
+	 */
+	protected Serializable getUpdateId(
+			Object entity,
+			EntityPersister persister,
+			Serializable requestedId,
+			EntityMode entityMode) {
 		// use the id assigned to the instance
-		Serializable id = persister.getIdentifier(entity, entityMode);
-		if ( id==null ) {
+		Serializable id = persister.getIdentifier( entity, entityMode );
+		if ( id == null ) {
 			// assume this is a newly instantiated transient object
 			// which should be saved rather than updated
 			throw new TransientObjectException(
 					"The given object has a null identifier: " +
-					persister.getEntityName()
-				);
+							persister.getEntityName()
+			);
 		}
 		else {
 			return id;
 		}
-			
+
 	}
 
-	protected void performUpdate(SaveOrUpdateEvent event, Object entity, EntityPersister persister) 
-	throws HibernateException {
-	
+	protected void performUpdate(
+			SaveOrUpdateEvent event,
+			Object entity,
+			EntityPersister persister) throws HibernateException {
+
 		if ( !persister.isMutable() ) {
 			log.trace( "immutable instance passed to doUpdate(), locking" );
 			reassociate( event, entity, event.getRequestedId(), persister );
@@ -246,27 +269,29 @@
 		else {
 
 			if ( log.isTraceEnabled() ) {
-				log.trace( 
-						"updating " + 
-						MessageHelper.infoString( persister, event.getRequestedId(), event.getSession().getFactory() ) 
-					);
+				log.trace(
+						"updating " +
+								MessageHelper.infoString(
+										persister, event.getRequestedId(), event.getSession().getFactory()
+								)
+				);
 			}
-	
+
 			final EventSource source = event.getSession();
-			
+
 			EntityKey key = new EntityKey( event.getRequestedId(), persister, source.getEntityMode() );
-			
+
 			source.getPersistenceContext().checkUniqueness( key, entity );
-	
+
 			if ( invokeUpdateLifecycle( entity, persister, source ) ) {
 				reassociate( event, event.getObject(), event.getRequestedId(), persister );
 				return;
 			}
-	
+
 			// this is a transient object with existing persistent state not loaded by the session
-	
-			new OnUpdateVisitor( source, event.getRequestedId() ).process( entity, persister );
-			
+
+			new OnUpdateVisitor( source, event.getRequestedId(), entity ).process( entity, persister );
+
 			//TODO: put this stuff back in to read snapshot from
 			//      the second-level cache (needs some extra work)
 			/*Object[] cachedState = null;
@@ -274,8 +299,8 @@
 			if ( persister.hasCache() ) {
 				CacheEntry entry = (CacheEntry) persister.getCache()
 						.get( event.getRequestedId(), source.getTimestamp() );
-			    cachedState = entry==null ? 
-			    		null : 
+			    cachedState = entry==null ?
+			    		null :
 			    		entry.getState(); //TODO: half-assemble this stuff
 			}*/
 
@@ -288,28 +313,28 @@
 					LockMode.NONE,
 					true,
 					persister,
-					false, 
+					false,
 					true //assume true, since we don't really know, and it doesn't matter
+			);
+
+			persister.afterReassociate( entity, source );
+
+			if ( log.isTraceEnabled() ) {
+				log.trace(
+						"updating " +
+								MessageHelper.infoString( persister, event.getRequestedId(), source.getFactory() )
 				);
-			
-			persister.afterReassociate(entity, source);
-	
-			if ( log.isTraceEnabled() ) {
-				log.trace( 
-						"updating " + 
-						MessageHelper.infoString( persister, event.getRequestedId(), source.getFactory() ) 
-					);
 			}
-	
-			cascadeOnUpdate(event, persister, entity);
-			
+
+			cascadeOnUpdate( event, persister, entity );
+
 		}
 	}
 
 	protected boolean invokeUpdateLifecycle(Object entity, EntityPersister persister, EventSource source) {
 		if ( persister.implementsLifecycle( source.getEntityMode() ) ) {
 			log.debug( "calling onUpdate()" );
-			if ( ( ( Lifecycle ) entity ).onUpdate(source) ) {
+			if ( ( ( Lifecycle ) entity ).onUpdate( source ) ) {
 				log.debug( "update vetoed by onUpdate()" );
 				return true;
 			}
@@ -329,8 +354,8 @@
 		EventSource source = event.getSession();
 		source.getPersistenceContext().incrementCascadeLevel();
 		try {
-			new Cascade(CascadingAction.SAVE_UPDATE, Cascade.AFTER_UPDATE, source)
-					.cascade(persister, entity);
+			new Cascade( CascadingAction.SAVE_UPDATE, Cascade.AFTER_UPDATE, source )
+					.cascade( persister, entity );
 		}
 		finally {
 			source.getPersistenceContext().decrementCascadeLevel();

Modified: trunk/Hibernate3/src/org/hibernate/event/def/OnLockVisitor.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/event/def/OnLockVisitor.java	2006-12-07 21:36:31 UTC (rev 10947)
+++ trunk/Hibernate3/src/org/hibernate/event/def/OnLockVisitor.java	2006-12-07 21:53:10 UTC (rev 10948)
@@ -14,60 +14,55 @@
  * When a transient entity is passed to lock(), we must inspect all its collections and
  * 1. associate any uninitialized PersistentCollections with this session
  * 2. associate any initialized PersistentCollections with this session, using the
- *    existing snapshot
+ * existing snapshot
  * 3. throw an exception for each "new" collection
  *
  * @author Gavin King
  */
 public class OnLockVisitor extends ReattachVisitor {
 
-	public OnLockVisitor(EventSource session, Serializable key) {
-		super(session, key);
+	public OnLockVisitor(EventSource session, Serializable key, Object owner) {
+		super( session, key, owner );
 	}
 
-	Object processCollection(Object collection, CollectionType type)
-		throws HibernateException {
+	Object processCollection(Object collection, CollectionType type) throws HibernateException {
 
 		SessionImplementor session = getSession();
 		CollectionPersister persister = session.getFactory().getCollectionPersister( type.getRole() );
 
-		if (collection==null) {
+		if ( collection == null ) {
 			//do nothing
 		}
 		else if ( collection instanceof PersistentCollection ) {
-			PersistentCollection persistentCollection = (PersistentCollection) collection;
-
-			if ( persistentCollection.setCurrentSession(session) ) {
-
-				if ( isOwnerUnchanged( persistentCollection, persister, getKey() ) ) {
+			PersistentCollection persistentCollection = ( PersistentCollection ) collection;
+			if ( persistentCollection.setCurrentSession( session ) ) {
+				if ( isOwnerUnchanged( persistentCollection, persister, extractCollectionKeyFromOwner( persister ) ) ) {
 					// a "detached" collection that originally belonged to the same entity
 					if ( persistentCollection.isDirty() ) {
-						throw new HibernateException("reassociated object has dirty collection");
+						throw new HibernateException( "reassociated object has dirty collection" );
 					}
-					reattachCollection(persistentCollection, type);
+					reattachCollection( persistentCollection, type );
 				}
 				else {
 					// a "detached" collection that belonged to a different entity
-					throw new HibernateException("reassociated object has dirty collection reference");
+					throw new HibernateException( "reassociated object has dirty collection reference" );
 				}
-
 			}
 			else {
 				// a collection loaded in the current session
 				// can not possibly be the collection belonging
 				// to the entity passed to update()
-				throw new HibernateException("reassociated object has dirty collection reference");
+				throw new HibernateException( "reassociated object has dirty collection reference" );
 			}
-
 		}
 		else {
 			// brand new collection
 			//TODO: or an array!! we can't lock objects with arrays now??
-			throw new HibernateException("reassociated object has dirty collection reference (or an array)");
+			throw new HibernateException( "reassociated object has dirty collection reference (or an array)" );
 		}
 
 		return null;
 
 	}
-	
+
 }

Modified: trunk/Hibernate3/src/org/hibernate/event/def/OnReplicateVisitor.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/event/def/OnReplicateVisitor.java	2006-12-07 21:36:31 UTC (rev 10947)
+++ trunk/Hibernate3/src/org/hibernate/event/def/OnReplicateVisitor.java	2006-12-07 21:53:10 UTC (rev 10948)
@@ -10,40 +10,43 @@
 import org.hibernate.type.CollectionType;
 
 /**
- * When an entity is passed to replicate(), and there is an existing row, we must 
+ * When an entity is passed to replicate(), and there is an existing row, we must
  * inspect all its collections and
  * 1. associate any uninitialized PersistentCollections with this session
  * 2. associate any initialized PersistentCollections with this session, using the
- *    existing snapshot
+ * existing snapshot
  * 3. execute a collection removal (SQL DELETE) for each null collection property
- *    or "new" collection
+ * or "new" collection
  *
  * @author Gavin King
  */
 public class OnReplicateVisitor extends ReattachVisitor {
-	
+
 	private boolean isUpdate;
-	
-	OnReplicateVisitor(EventSource session, Serializable key, boolean isUpdate) {
-		super(session, key);
+
+	OnReplicateVisitor(EventSource session, Serializable key, Object owner, boolean isUpdate) {
+		super( session, key, owner );
 		this.isUpdate = isUpdate;
 	}
 
 	Object processCollection(Object collection, CollectionType type)
-		throws HibernateException {
-		
-		if (collection==CollectionType.UNFETCHED_COLLECTION) return null;
+			throws HibernateException {
 
+		if ( collection == CollectionType.UNFETCHED_COLLECTION ) {
+			return null;
+		}
+
 		EventSource session = getSession();
-		Serializable key = getKey();
 		CollectionPersister persister = session.getFactory().getCollectionPersister( type.getRole() );
 
-		if (isUpdate) removeCollection(persister, key, session);
-		if ( collection!=null && (collection instanceof PersistentCollection) ) {
-			PersistentCollection wrapper = (PersistentCollection) collection;
-			wrapper.setCurrentSession(session);
+		if ( isUpdate ) {
+			removeCollection( persister, extractCollectionKeyFromOwner( persister ), session );
+		}
+		if ( collection != null && ( collection instanceof PersistentCollection ) ) {
+			PersistentCollection wrapper = ( PersistentCollection ) collection;
+			wrapper.setCurrentSession( session );
 			if ( wrapper.wasInitialized() ) {
-				session.getPersistenceContext().addNewCollection(persister, wrapper);
+				session.getPersistenceContext().addNewCollection( persister, wrapper );
 			}
 			else {
 				reattachCollection( wrapper, type );

Modified: trunk/Hibernate3/src/org/hibernate/event/def/OnUpdateVisitor.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/event/def/OnUpdateVisitor.java	2006-12-07 21:36:31 UTC (rev 10947)
+++ trunk/Hibernate3/src/org/hibernate/event/def/OnUpdateVisitor.java	2006-12-07 21:53:10 UTC (rev 10948)
@@ -21,51 +21,49 @@
  */
 public class OnUpdateVisitor extends ReattachVisitor {
 
-	OnUpdateVisitor(EventSource session, Serializable key) {
-		super(session, key);
+	OnUpdateVisitor(EventSource session, Serializable key, Object owner) {
+		super( session, key, owner );
 	}
 
-	Object processCollection(Object collection, CollectionType type)
-		throws HibernateException {
-		
-		if (collection==CollectionType.UNFETCHED_COLLECTION) return null;
+	/**
+	 * {@inheritDoc}
+	 */
+	Object processCollection(Object collection, CollectionType type) throws HibernateException {
 
+		if ( collection == CollectionType.UNFETCHED_COLLECTION ) {
+			return null;
+		}
+
 		EventSource session = getSession();
-		Serializable key = getKey();
 		CollectionPersister persister = session.getFactory().getCollectionPersister( type.getRole() );
 
+		final Serializable collectionKey = extractCollectionKeyFromOwner( persister );
 		if ( collection!=null && (collection instanceof PersistentCollection) ) {
 			PersistentCollection wrapper = (PersistentCollection) collection;
-
 			if ( wrapper.setCurrentSession(session) ) {
 				//a "detached" collection!
-
-				if ( !isOwnerUnchanged(wrapper, persister, key) ) {
+				if ( !isOwnerUnchanged( wrapper, persister, collectionKey ) ) {
 					// if the collection belonged to a different entity,
 					// clean up the existing state of the collection
-					removeCollection(persister, key, session);
+					removeCollection( persister, collectionKey, session );
 				}
-
 				reattachCollection(wrapper, type);
 			}
 			else {
 				// a collection loaded in the current session
 				// can not possibly be the collection belonging
 				// to the entity passed to update()
-				removeCollection(persister, key, session);
+				removeCollection(persister, collectionKey, session);
 			}
-
 		}
 		else {
 			// null or brand new collection
 			// this will also (inefficiently) handle arrays, which have
 			// no snapshot, so we can't do any better
-			removeCollection(persister, key, session);
-			//processArrayOrNewCollection(collection, type);
+			removeCollection(persister, collectionKey, session);
 		}
 
 		return null;
-
 	}
 
 }

Modified: trunk/Hibernate3/src/org/hibernate/event/def/ReattachVisitor.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/event/def/ReattachVisitor.java	2006-12-07 21:36:31 UTC (rev 10947)
+++ trunk/Hibernate3/src/org/hibernate/event/def/ReattachVisitor.java	2006-12-07 21:53:10 UTC (rev 10948)
@@ -14,34 +14,51 @@
 import org.hibernate.type.Type;
 
 /**
- * Abstract superclass of visitors that reattach collections
+ * Abstract superclass of visitors that reattach collections.
+ *
  * @author Gavin King
  */
 public abstract class ReattachVisitor extends ProxyVisitor {
-	
-	private static final Log log = LogFactory.getLog(ReattachVisitor.class);
 
-	private final Serializable key;
+	private static final Log log = LogFactory.getLog( ReattachVisitor.class );
 
-	final Serializable getKey() {
-		return key;
+	private final Serializable ownerIdentifier;
+	private final Object owner;
+
+	public ReattachVisitor(EventSource session, Serializable ownerIdentifier, Object owner) {
+		super( session );
+		this.ownerIdentifier = ownerIdentifier;
+		this.owner = owner;
 	}
 
-	public ReattachVisitor(EventSource session, Serializable key) {
-		super(session);
-		this.key=key;
+	/**
+	 * Retrieve the identifier of the entity being visited.
+	 *
+	 * @return The entity's identifier.
+	 */
+	final Serializable getOwnerIdentifier() {
+		return ownerIdentifier;
 	}
 
-	Object processComponent(Object component, AbstractComponentType componentType)
-	throws HibernateException {
+	/**
+	 * Retrieve the entity being visited.
+	 *
+	 * @return The entity.
+	 */
+	final Object getOwner() {
+		return owner;
+	}
 
+	/**
+	 * {@inheritDoc}
+	 */
+	Object processComponent(Object component, AbstractComponentType componentType) throws HibernateException {
 		Type[] types = componentType.getSubtypes();
-		if (component==null) {
+		if ( component == null ) {
 			processValues( new Object[types.length], types );
 		}
 		else {
-			super.processComponent(component, componentType);
-			//processValues( componentType.getPropertyValues( component, getSession() ), types );
+			super.processComponent( component, componentType );
 		}
 
 		return null;
@@ -51,23 +68,36 @@
 	 * Schedules a collection for deletion.
 	 *
 	 * @param role The persister representing the collection to be removed.
-	 * @param id The id of the entity containing the collection to be removed.
+	 * @param collectionKey The collection key (differs from owner-id in the case of property-refs).
+	 * @param source The session from which the request originated.
 	 * @throws HibernateException
 	 */
-	public void removeCollection(CollectionPersister role, Serializable id, EventSource source) 
-	throws HibernateException {
-		if ( log.isTraceEnabled() )
+	void removeCollection(CollectionPersister role, Serializable collectionKey, EventSource source) throws HibernateException {
+		if ( log.isTraceEnabled() ) {
 			log.trace(
 					"collection dereferenced while transient " +
-					MessageHelper.collectionInfoString( role, id, source.getFactory() )
+					MessageHelper.collectionInfoString( role, ownerIdentifier, source.getFactory() )
 			);
-		/*if ( role.hasOrphanDelete() ) {
-			throw new HibernateException(
-				"You may not dereference a collection with cascade=\"all-delete-orphan\": " +
-				MessageHelper.infoString(role, id)
-			);
-		}*/
-		source.getActionQueue().addAction( new CollectionRemoveAction( null, role, id, false, source ) );
+		}
+		source.getActionQueue().addAction( new CollectionRemoveAction( null, role, collectionKey, false, source ) );
 	}
 
+	/**
+	 * This version is slightly different for say
+	 * {@link org.hibernate.type.CollectionType#getKeyOfOwner} in that here we
+	 * need to assume that the owner is not yet associated with the session,
+	 * and thus we cannot rely on the owner's EntityEntry snapshot...
+	 *
+	 * @param role The persister for the collection role being processed.
+	 * @return
+	 */
+	final Serializable extractCollectionKeyFromOwner(CollectionPersister role) {
+		if ( role.getCollectionType().useLHSPrimaryKey() ) {
+			return ownerIdentifier;
+		}
+		else {
+			return ( Serializable ) role.getOwnerEntityPersister().getPropertyValue( owner, role.getCollectionType().getLHSPropertyName(), getSession().getEntityMode() );
+		}
+
+	}
 }

Modified: trunk/Hibernate3/test/org/hibernate/test/propertyref/basic/Person.hbm.xml
===================================================================
--- trunk/Hibernate3/test/org/hibernate/test/propertyref/basic/Person.hbm.xml	2006-12-07 21:36:31 UTC (rev 10947)
+++ trunk/Hibernate3/test/org/hibernate/test/propertyref/basic/Person.hbm.xml	2006-12-07 21:53:10 UTC (rev 10948)
@@ -1,17 +1,17 @@
 <?xml version="1.0"?>
-<!DOCTYPE hibernate-mapping PUBLIC 
-	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
-	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+<!DOCTYPE hibernate-mapping PUBLIC
+        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 
 <!--
 
   Demonstrates the use of property-ref to map legacy data where
   foreign keys reference something other than the primary key of
   the associated entity. Here we show:
-  
-  (1) A one-to-one foreign key association (prefer primary key 
+
+  (1) A one-to-one foreign key association (prefer primary key
       associations)
-      
+
   (2) A bidirectional one-to-many association on a key that is
       not the primary key (prefer associations from foreign keys
       to primary keys)
@@ -20,57 +20,47 @@
 
 <hibernate-mapping package="org.hibernate.test.propertyref.basic">
 
-	<class name="Person">
-		<id name="id">
-			<generator class="hilo"/>
-		</id>
-
-		<property name="name" length="100"/>
-		<property name="userId" column="person_userid" length="8" unique="true"/>
-
-		<one-to-one name="address" property-ref="person" cascade="all" fetch="join"/>
-
-		<set name="accounts" inverse="true">
-			<key column="userId" property-ref="userId"/>
-			<one-to-many class="Account"/>
-		</set>
-
-        <bag name="systems" table="USER_SYSTEM" lazy="false" inverse="false" cascade="all">
+    <class name="Person" table="PROPREF_PERS">
+        <id name="id">
+            <generator class="hilo"/>
+        </id>
+        <property name="name" length="100"/>
+        <property name="userId" column="person_userid" length="8" unique="true"/>
+        <one-to-one name="address" property-ref="person" cascade="all" fetch="join"/>
+        <set name="accounts" inverse="true">
+            <key column="userId" property-ref="userId"/>
+            <one-to-many class="Account"/>
+        </set>
+        <bag name="systems" table="USER_SYSTEM" lazy="true" inverse="false" cascade="all">
             <key column="USER_ID" property-ref="userId" />
             <element type="string" column="SYSTEM" />
         </bag>
     </class>
 
-	<class name="Address">
-		<id name="id">
-			<generator class="hilo"/>
-		</id>
+    <class name="Address" table="PROPREF_ADDR">
+        <id name="id">
+            <generator class="hilo"/>
+        </id>
+        <property name="address" length="300"/>
+        <property name="zip" length="5"/>
+        <property name="country" length="25"/>
+        <many-to-one name="person" unique="true" not-null="true"/>
+    </class>
 
-		<property name="address" length="300"/>
-		<property name="zip" length="5"/>
-		<property name="country" length="25"/>
-		<many-to-one name="person" unique="true" not-null="true"/>
-	</class>
-	
-	<class name="Account">
-		<id name="accountId" length="32">
-			<generator class="uuid.hex"/>
-		</id>
-		
-		<many-to-one name="user" 
-			column="userId"
-			property-ref="userId"/>
-		
-		<property name="type" not-null="true"/>
-		
-	</class>
-	
-	<class name="Group" table="`Group`">
-		<id name="name"/>
-		<set name="users" table="UserGroup" cascade="save-update">
-			<key column="groupName"/>
-			<many-to-many column="userId" class="Person" property-ref="userId"/>
-		</set>
-	</class>
+    <class name="Account" table="PROPREF_ACCT">
+        <id name="accountId" length="32">
+            <generator class="uuid.hex"/>
+        </id>
+        <many-to-one name="user" column="userId" property-ref="userId"/>
+        <property name="type" not-null="true"/>
+    </class>
 
+    <class name="Group" table="PROPREF_GRP">
+        <id name="name"/>
+        <set name="users" table="PROPREF_USERGROUP" cascade="save-update">
+            <key column="groupName"/>
+            <many-to-many column="userId" class="Person" property-ref="userId"/>
+        </set>
+    </class>
+
 </hibernate-mapping>
\ No newline at end of file

Modified: trunk/Hibernate3/test/org/hibernate/test/propertyref/basic/PropertyRefTest.java
===================================================================
--- trunk/Hibernate3/test/org/hibernate/test/propertyref/basic/PropertyRefTest.java	2006-12-07 21:36:31 UTC (rev 10947)
+++ trunk/Hibernate3/test/org/hibernate/test/propertyref/basic/PropertyRefTest.java	2006-12-07 21:53:10 UTC (rev 10948)
@@ -60,7 +60,7 @@
 		t = s.beginTransaction();
 		s.createQuery( "from Person" ).list();
 		s.clear();
-		s.createSQLQuery( "select {p.*} from Person {p}" )
+		s.createSQLQuery( "select {p.*} from PROPREF_PERS {p}" )
 				.addEntity( "p", Person.class.getName() )
 				.list();
 		t.commit();




More information about the hibernate-commits mailing list