[hibernate-commits] Hibernate SVN: r10311 - branches/Branch_3_2/Hibernate3/src/org/hibernate/engine
hibernate-commits at lists.jboss.org
hibernate-commits at lists.jboss.org
Tue Aug 22 17:29:58 EDT 2006
Author: steve.ebersole at jboss.com
Date: 2006-08-22 17:29:27 -0400 (Tue, 22 Aug 2006)
New Revision: 10311
Modified:
branches/Branch_3_2/Hibernate3/src/org/hibernate/engine/Cascade.java
branches/Branch_3_2/Hibernate3/src/org/hibernate/engine/CascadingAction.java
Log:
cleanup
Modified: branches/Branch_3_2/Hibernate3/src/org/hibernate/engine/Cascade.java
===================================================================
--- branches/Branch_3_2/Hibernate3/src/org/hibernate/engine/Cascade.java 2006-08-22 21:28:18 UTC (rev 10310)
+++ branches/Branch_3_2/Hibernate3/src/org/hibernate/engine/Cascade.java 2006-08-22 21:29:27 UTC (rev 10311)
@@ -20,31 +20,14 @@
import org.hibernate.util.CollectionHelper;
/**
- * Implements cascaded save / delete / update / lock / evict / replicate / persist / merge
+ * Delegate responsible for, in conjunction with the various
+ * {@link CascadingAction actions}, implementing cascade processing.
*
- * @see org.hibernate.type.AssociationType
* @author Gavin King
+ * @see CascadingAction
*/
public final class Cascade {
-
- private int cascadeTo;
- private EventSource eventSource;
- private CascadingAction action;
- public Cascade(
- final CascadingAction action,
- final int cascadeTo,
- final EventSource eventSource
- ) {
- this.cascadeTo = cascadeTo;
- this.eventSource = eventSource;
- this.action = action;
- }
-
- private static final Log log = LogFactory.getLog(Cascade.class);
-
- // The available cascade actions:
-
/**
* A cascade point that occurs just after the insertion of the parent entity and
* just before deletion
@@ -88,29 +71,107 @@
*/
public static final int BEFORE_MERGE = 0;
- // The allowable cascade styles for a property:
+ private static final Log log = LogFactory.getLog( Cascade.class );
+
+
+ private int cascadeTo;
+ private EventSource eventSource;
+ private CascadingAction action;
+
+ public Cascade(final CascadingAction action, final int cascadeTo, final EventSource eventSource) {
+ this.cascadeTo = cascadeTo;
+ this.eventSource = eventSource;
+ this.action = action;
+ }
+
/**
+ * Cascade an action from the parent entity instance to all its children.
+ *
+ * @param persister The parent's entity persister
+ * @param parent The parent reference.
+ * @throws HibernateException
+ */
+ public void cascade(final EntityPersister persister, final Object parent)
+ throws HibernateException {
+ cascade( persister, parent, null );
+ }
+
+ /**
+ * Cascade an action from the parent entity instance to all its children. This
+ * form is typicaly called from within cascade actions.
+ *
+ * @param persister The parent's entity persister
+ * @param parent The parent reference.
+ * @param anything Anything ;) Typically some form of cascade-local cache
+ * which is specific to each CascadingAction type
+ * @throws HibernateException
+ */
+ public void cascade(final EntityPersister persister, final Object parent, final Object anything)
+ throws HibernateException {
+
+ if ( persister.hasCascades() || action.requiresNoCascadeChecking() ) { // performance opt
+ if ( log.isTraceEnabled() ) {
+ log.trace( "processing cascade " + action + " for: " + persister.getEntityName() );
+ }
+
+ Type[] types = persister.getPropertyTypes();
+ CascadeStyle[] cascadeStyles = persister.getPropertyCascadeStyles();
+ EntityMode entityMode = eventSource.getEntityMode();
+ boolean hasUninitializedLazyProperties = persister.hasUninitializedLazyProperties( parent, entityMode );
+ for ( int i=0; i<types.length; i++) {
+ CascadeStyle style = cascadeStyles[i];
+ if ( hasUninitializedLazyProperties && persister.getPropertyLaziness()[i] && ! action.performOnLazyProperty() ) {
+ //do nothing to avoid a lazy property initialization
+ continue;
+ }
+
+ if ( style.doCascade( action ) ) {
+ cascadeProperty(
+ persister.getPropertyValue( parent, i, entityMode ),
+ types[i],
+ style,
+ anything,
+ false
+ );
+ }
+ else if ( action.requiresNoCascadeChecking() ) {
+ action.noCascade(
+ eventSource,
+ persister.getPropertyValue( parent, i, entityMode ),
+ parent,
+ persister,
+ i
+ );
+ }
+ }
+
+ if ( log.isTraceEnabled() ) {
+ log.trace( "done processing cascade " + action + " for: " + persister.getEntityName() );
+ }
+ }
+ }
+
+ /**
* Cascade an action to the child or children
*/
private void cascadeProperty(
- final Object child,
- final Type type,
- final CascadeStyle style,
- final Object anything,
- final boolean isCascadeDeleteEnabled)
- throws HibernateException {
+ final Object child,
+ final Type type,
+ final CascadeStyle style,
+ final Object anything,
+ final boolean isCascadeDeleteEnabled) throws HibernateException {
if (child!=null) {
if ( type.isAssociationType() ) {
AssociationType associationType = (AssociationType) type;
if ( cascadeAssociationNow( associationType ) ) {
- cascadeAssociation(
- child,
- type,
- style,
- anything,
- isCascadeDeleteEnabled
+ cascadeAssociation(
+ child,
+ type,
+ style,
+ anything,
+ isCascadeDeleteEnabled
);
}
}
@@ -126,20 +187,19 @@
}
private void cascadeComponent(
- final Object child,
- final AbstractComponentType componentType,
- final Object anything
- ) {
+ final Object child,
+ final AbstractComponentType componentType,
+ final Object anything) {
Object[] children = componentType.getPropertyValues(child, eventSource);
Type[] types = componentType.getSubtypes();
for ( int i=0; i<types.length; i++ ) {
CascadeStyle componentPropertyStyle = componentType.getCascadeStyle(i);
if ( componentPropertyStyle.doCascade(action) ) {
- cascadeProperty(
- children[i],
- types[i],
- componentPropertyStyle,
- anything,
+ cascadeProperty(
+ children[i],
+ types[i],
+ componentPropertyStyle,
+ anything,
false
);
}
@@ -147,12 +207,11 @@
}
private void cascadeAssociation(
- final Object child,
- final Type type,
+ final Object child,
+ final Type type,
final CascadeStyle style,
- final Object anything,
- final boolean isCascadeDeleteEnabled
- ) {
+ final Object anything,
+ final boolean isCascadeDeleteEnabled) {
if ( type.isEntityType() || type.isAnyType() ) {
cascadeToOne( child, type, style, anything, isCascadeDeleteEnabled );
}
@@ -160,17 +219,15 @@
cascadeCollection( child, style, anything, (CollectionType) type );
}
}
-
+
/**
* Cascade an action to a collection
*/
private void cascadeCollection(
- final Object child,
- final CascadeStyle style,
- final Object anything,
- final CollectionType type
- ) {
-
+ final Object child,
+ final CascadeStyle style,
+ final Object anything,
+ final CollectionType type) {
CollectionPersister persister = eventSource.getFactory()
.getCollectionPersister( type.getRole() );
Type elemType = persister.getElementType();
@@ -179,161 +236,93 @@
if ( cascadeTo==AFTER_INSERT_BEFORE_DELETE) {
cascadeTo = AFTER_INSERT_BEFORE_DELETE_VIA_COLLECTION;
}
-
+
//cascade to current collection elements
if ( elemType.isEntityType() || elemType.isAnyType() || elemType.isComponentType() ) {
cascadeCollectionElements(
- child,
- type,
- style,
+ child,
+ type,
+ style,
elemType,
- anything,
- persister.isCascadeDeleteEnabled()
+ anything,
+ persister.isCascadeDeleteEnabled()
);
}
-
+
cascadeTo = oldCascadeTo;
}
-
+
/**
* Cascade an action to a to-one association or any type
*/
private void cascadeToOne(
- final Object child,
- final Type type,
- final CascadeStyle style,
- final Object anything,
- final boolean isCascadeDeleteEnabled
- ) {
-
- final String entityName = type.isEntityType() ?
- ( (EntityType) type ).getAssociatedEntityName() : null;
-
+ final Object child,
+ final Type type,
+ final CascadeStyle style,
+ final Object anything,
+ final boolean isCascadeDeleteEnabled) {
+ final String entityName = type.isEntityType()
+ ? ( (EntityType) type ).getAssociatedEntityName()
+ : null;
if ( style.reallyDoCascade(action) ) { //not really necessary, but good for consistency...
action.cascade(eventSource, child, entityName, anything, isCascadeDeleteEnabled);
}
-
}
/**
- * Cascade an action from the parent entity instance to all its children
- */
- public void cascade(final EntityPersister persister, final Object parent)
- throws HibernateException {
- cascade(persister, parent, null);
- }
-
- /**
- * Cascade an action from the parent entity instance to all its children
- */
- public void cascade(
- final EntityPersister persister,
- final Object parent,
- final Object anything)
- throws HibernateException {
-
- if ( persister.hasCascades() || action.requiresNoCascadeChecking() ) { // performance opt
- if ( log.isTraceEnabled() ) {
- log.trace( "processing cascade " + action + " for: " + persister.getEntityName() );
- }
-
- Type[] types = persister.getPropertyTypes();
- CascadeStyle[] cascadeStyles = persister.getPropertyCascadeStyles();
- for ( int i=0; i<types.length; i++) {
- CascadeStyle style = cascadeStyles[i];
- EntityMode entityMode = eventSource.getEntityMode();
- if ( persister.getPropertyLaziness()[i]
- && ! action.performOnLazyProperty()
- && persister.hasUninitializedLazyProperties( parent, entityMode )
- //currently there is no way to lazy a property an not the others
- ) {
- //do nothing to avoid a lazy property initialization
- }
- else if ( style.doCascade(action) ) {
- cascadeProperty(
- persister.getPropertyValue( parent, i, entityMode ),
- types[i],
- style,
- anything,
- false
- );
- }
- else {
-
- if ( action.requiresNoCascadeChecking() ) {
- action.noCascade(
- eventSource,
- persister.getPropertyValue( parent, i, entityMode ),
- parent,
- persister,
- i
- );
- }
- }
- }
-
- if ( log.isTraceEnabled() ) {
- log.trace( "done processing cascade " + action + " for: " + persister.getEntityName() );
- }
- }
- }
-
- /**
* Cascade to the collection elements
*/
private void cascadeCollectionElements(
- final Object child,
- final CollectionType collectionType,
- final CascadeStyle style,
- final Type elemType,
- final Object anything,
- final boolean isCascadeDeleteEnabled)
- throws HibernateException {
-
+ final Object child,
+ final CollectionType collectionType,
+ final CascadeStyle style,
+ final Type elemType,
+ final Object anything,
+ final boolean isCascadeDeleteEnabled) throws HibernateException {
// we can't cascade to non-embedded elements
boolean embeddedElements = eventSource.getEntityMode()!=EntityMode.DOM4J ||
( (EntityType) collectionType.getElementType( eventSource.getFactory() ) ).isEmbeddedInXML();
-
- boolean reallyDoCascade = style.reallyDoCascade(action) &&
+
+ boolean reallyDoCascade = style.reallyDoCascade(action) &&
embeddedElements && child!=CollectionType.UNFETCHED_COLLECTION;
-
+
if ( reallyDoCascade ) {
if ( log.isTraceEnabled() ) {
log.trace( "cascade " + action + " for collection: " + collectionType.getRole() );
}
-
+
Iterator iter = action.getCascadableChildrenIterator(eventSource, collectionType, child);
while ( iter.hasNext() ) {
cascadeProperty(
- iter.next(),
+ iter.next(),
elemType,
- style,
- anything,
- isCascadeDeleteEnabled
+ style,
+ anything,
+ isCascadeDeleteEnabled
);
}
-
+
if ( log.isTraceEnabled() ) {
log.trace( "done cascade " + action + " for collection: " + collectionType.getRole() );
}
}
-
- final boolean deleteOrphans = style.hasOrphanDelete() &&
- action.deleteOrphans() &&
- elemType.isEntityType() &&
+
+ final boolean deleteOrphans = style.hasOrphanDelete() &&
+ action.deleteOrphans() &&
+ elemType.isEntityType() &&
child instanceof PersistentCollection; //a newly instantiated collection can't have orphans
-
+
if ( deleteOrphans ) { // handle orphaned entities!!
if ( log.isTraceEnabled() ) {
log.trace( "deleting orphans for collection: " + collectionType.getRole() );
}
-
+
// we can do the cast since orphan-delete does not apply to:
// 1. newly instantiated collections
// 2. arrays (we can't track orphans for detached arrays)
final String entityName = collectionType.getAssociatedEntityName( eventSource.getFactory() );
deleteOrphans( entityName, (PersistentCollection) child );
-
+
if ( log.isTraceEnabled() ) {
log.trace( "done deleting orphans for collection: " + collectionType.getRole() );
}
@@ -343,21 +332,19 @@
/**
* Delete any entities that were removed from the collection
*/
- private void deleteOrphans(String entityName, PersistentCollection pc)
- throws HibernateException {
-
- final Collection orphans;
+ private void deleteOrphans(String entityName, PersistentCollection pc) throws HibernateException {
//TODO: suck this logic into the collection!
+ final Collection orphans;
if ( pc.wasInitialized() ) {
CollectionEntry ce = eventSource.getPersistenceContext().getCollectionEntry(pc);
- orphans = ce==null ?
+ orphans = ce==null ?
CollectionHelper.EMPTY_COLLECTION :
ce.getOrphans(entityName, pc);
}
else {
orphans = pc.getQueuedOrphans(entityName);
}
-
+
final Iterator orphanIter = orphans.iterator();
while ( orphanIter.hasNext() ) {
Object orphan = orphanIter.next();
@@ -368,7 +355,6 @@
eventSource.delete( entityName, orphan, false, null );
}
}
-
}
}
Modified: branches/Branch_3_2/Hibernate3/src/org/hibernate/engine/CascadingAction.java
===================================================================
--- branches/Branch_3_2/Hibernate3/src/org/hibernate/engine/CascadingAction.java 2006-08-22 21:28:18 UTC (rev 10310)
+++ branches/Branch_3_2/Hibernate3/src/org/hibernate/engine/CascadingAction.java 2006-08-22 21:29:27 UTC (rev 10311)
@@ -20,28 +20,95 @@
/**
* A session action that may be cascaded from parent entity to its children
- *
+ *
* @author Gavin King
*/
public abstract class CascadingAction {
- private static final Log log = LogFactory.getLog(CascadingAction.class);
+ private static final Log log = LogFactory.getLog( CascadingAction.class );
+
+ // the CascadingAction contract ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
/**
- * cascade the action to the child object
+ * protected constructor
*/
- public abstract void cascade(EventSource session, Object child, String entityName, Object anything, boolean isCascadeDeleteEnabled)
- throws HibernateException;
+ CascadingAction() {
+ }
+
/**
- * Should this action be cascaded to the given (possibly uninitialized) collection?
+ * Cascade the action to the child object.
+ *
+ * @param session The session within which the cascade is occuring.
+ * @param child The child to which cascading should be performed.
+ * @param entityName The child's entity name
+ * @param anything Anything ;) Typically some form of cascade-local cache
+ * which is specific to each CascadingAction type
+ * @param isCascadeDeleteEnabled Are cascading deletes enabled.
+ * @throws HibernateException
*/
- public abstract Iterator getCascadableChildrenIterator(EventSource session, CollectionType collectionType, Object collection);
+ public abstract void cascade(
+ EventSource session,
+ Object child,
+ String entityName,
+ Object anything,
+ boolean isCascadeDeleteEnabled) throws HibernateException;
+
/**
- * Do we need to handle orphan delete for this action?
+ * Given a collection, get an iterator of the children upon which the
+ * current cascading action should be visited.
+ *
+ * @param session The session within which the cascade is occuring.
+ * @param collectionType The mapping type of the collection.
+ * @param collection The collection instance.
+ * @return The children iterator.
*/
+ public abstract Iterator getCascadableChildrenIterator(
+ EventSource session,
+ CollectionType collectionType,
+ Object collection);
+
+ /**
+ * Does this action potentially extrapolate to orphan deletes?
+ *
+ * @return True if this action can lead to deletions of orphans.
+ */
public abstract boolean deleteOrphans();
+
/**
+ * Does the specified cascading action require verification of no cascade validity?
+ *
+ * @return True if this action requires no-cascade verification; false otherwise.
+ */
+ public boolean requiresNoCascadeChecking() {
+ return false;
+ }
+
+ /**
+ * Called (in the case of {@link #requiresNoCascadeChecking} returning true) to validate
+ * that no cascade on the given property is considered a valid semantic.
+ *
+ * @param session The session witin which the cascade is occurring.
+ * @param child The property value
+ * @param parent The property value owner
+ * @param persister The entity persister for the owner
+ * @param propertyIndex The index of the property within the owner.
+ */
+ public void noCascade(EventSource session, Object child, Object parent, EntityPersister persister, int propertyIndex) {
+ }
+
+ /**
+ * Should this action be performed (or noCascade consulted) in the case of lazy properties.
+ */
+ public boolean performOnLazyProperty() {
+ return true;
+ }
+
+
+ // the CascadingAction implementations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ /**
* @see org.hibernate.Session#delete(Object)
*/
public static final CascadingAction DELETE = new CascadingAction() {
@@ -326,22 +393,25 @@
}
};
- CascadingAction() {}
- public boolean requiresNoCascadeChecking() {
- return false;
- }
+ // static helper methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- public void noCascade(EventSource session, Object child, Object parent, EntityPersister persister, int propertyIndex) {
- }
-
/**
- * Iterate all the collection elements, loading them from the database if necessary.
+ * Given a collection, get an iterator of all its children, loading them
+ * from the database if necessary.
+ *
+ * @param session The session within which the cascade is occuring.
+ * @param collectionType The mapping type of the collection.
+ * @param collection The collection instance.
+ * @return The children iterator.
*/
- private static Iterator getAllElementsIterator(EventSource session, CollectionType collectionType, Object collection) {
- return collectionType.getElementsIterator(collection, session);
+ private static Iterator getAllElementsIterator(
+ EventSource session,
+ CollectionType collectionType,
+ Object collection) {
+ return collectionType.getElementsIterator( collection, session );
}
+
/**
* Iterate just the elements of the collection that are already there. Don't load
* any new elements from the database.
@@ -362,7 +432,4 @@
return !(collection instanceof PersistentCollection) || ( (PersistentCollection) collection ).wasInitialized();
}
- public boolean performOnLazyProperty() {
- return true;
- }
}
\ No newline at end of file
More information about the hibernate-commits
mailing list