HHH-9328 Avoids creation of Cascade objects at all

by converting all methods of the Cascade class into
static methods.
This commit is contained in:
Andrej Golovnin 2014-11-27 20:43:44 +01:00
parent 2105f2a49d
commit fb15ee548c
10 changed files with 130 additions and 53 deletions

View File

@ -58,22 +58,8 @@
public final class Cascade {
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( Cascade.class );
private int componentPathStackDepth = 0;
private final CascadingAction action;
private final EventSource eventSource;
private CascadePoint cascadePoint;
/**
* Constructs a Cascade
*
* @param action The action we are cascading
* @param cascadePoint The point in the action at which we are trying to cascade currently
* @param eventSource The session
*/
public Cascade(final CascadingAction action, final CascadePoint cascadePoint, final EventSource eventSource) {
this.cascadePoint = cascadePoint;
this.eventSource = eventSource;
this.action = action;
private Cascade() {
// NOP
}
/**
@ -81,9 +67,13 @@ public Cascade(final CascadingAction action, final CascadePoint cascadePoint, fi
*
* @param persister The parent's entity persister
* @param parent The parent reference.
* @throws HibernateException
*/
public void cascade(final EntityPersister persister, final Object parent) {
cascade( persister, parent, null );
public static void cascade(
final CascadingAction action, final CascadePoint cascadePoint,
final EventSource eventSource, final EntityPersister persister, final Object parent)
throws HibernateException {
cascade( action, cascadePoint, eventSource, persister, parent, null );
}
/**
@ -95,9 +85,12 @@ public void cascade(final EntityPersister persister, final Object parent) {
* @param anything Anything ;) Typically some form of cascade-local cache
* which is specific to each CascadingAction type
*/
public void cascade(final EntityPersister persister, final Object parent, final Object anything) {
if ( persister.hasCascades() || action.requiresNoCascadeChecking() ) {
// performance opt
public static void cascade(
final CascadingAction action, final CascadePoint cascadePoint,
final EventSource eventSource, final EntityPersister persister, final Object parent, final Object anything)
throws HibernateException {
if ( persister.hasCascades() || action.requiresNoCascadeChecking() ) { // performance opt
final boolean traceEnabled = LOG.isTraceEnabled();
if ( traceEnabled ) {
LOG.tracev( "Processing cascade {0} for: {1}", action, persister.getEntityName() );
@ -106,6 +99,7 @@ public void cascade(final EntityPersister persister, final Object parent, final
final Type[] types = persister.getPropertyTypes();
final CascadeStyle[] cascadeStyles = persister.getPropertyCascadeStyles();
final boolean hasUninitializedLazyProperties = persister.hasUninitializedLazyProperties( parent );
final int componentPathStackDepth = 0;
for ( int i=0; i<types.length; i++) {
final CascadeStyle style = cascadeStyles[i];
final String propertyName = persister.getPropertyNames()[i];
@ -116,6 +110,10 @@ public void cascade(final EntityPersister persister, final Object parent, final
if ( style.doCascade( action ) ) {
cascadeProperty(
action,
cascadePoint,
eventSource,
componentPathStackDepth,
parent,
persister.getPropertyValue( parent, i ),
types[i],
@ -145,7 +143,11 @@ else if ( action.requiresNoCascadeChecking() ) {
/**
* Cascade an action to the child or children
*/
private void cascadeProperty(
private static void cascadeProperty(
final CascadingAction action,
final CascadePoint cascadePoint,
final EventSource eventSource,
final int componentPathStackDepth,
final Object parent,
final Object child,
final Type type,
@ -157,8 +159,12 @@ private void cascadeProperty(
if ( child != null ) {
if ( type.isAssociationType() ) {
final AssociationType associationType = (AssociationType) type;
if ( cascadeAssociationNow( associationType ) ) {
if ( cascadeAssociationNow( cascadePoint, associationType ) ) {
cascadeAssociation(
action,
cascadePoint,
eventSource,
componentPathStackDepth,
parent,
child,
type,
@ -169,7 +175,17 @@ private void cascadeProperty(
}
}
else if ( type.isComponentType() ) {
cascadeComponent( parent, child, (CompositeType) type, propertyName, anything );
cascadeComponent(
action,
cascadePoint,
eventSource,
componentPathStackDepth,
parent,
child,
(CompositeType) type,
propertyName,
anything
);
}
}
@ -247,21 +263,25 @@ else if ( type.isComponentType() ) {
*
* @return True if the attribute represents a logical one to one association
*/
private boolean isLogicalOneToOne(Type type) {
private static boolean isLogicalOneToOne(Type type) {
return type.isEntityType() && ( (EntityType) type ).isLogicalOneToOne();
}
private boolean cascadeAssociationNow(AssociationType associationType) {
private static boolean cascadeAssociationNow(final CascadePoint cascadePoint, AssociationType associationType) {
return associationType.getForeignKeyDirection().cascadeNow( cascadePoint );
}
private void cascadeComponent(
private static void cascadeComponent(
final CascadingAction action,
final CascadePoint cascadePoint,
final EventSource eventSource,
final int componentPathStackDepth,
final Object parent,
final Object child,
final CompositeType componentType,
final String componentPropertyName,
final Object anything) {
componentPathStackDepth++;
final Object[] children = componentType.getPropertyValues( child, eventSource );
final Type[] types = componentType.getSubtypes();
for ( int i=0; i<types.length; i++ ) {
@ -269,6 +289,10 @@ private void cascadeComponent(
final String subPropertyName = componentType.getPropertyNames()[i];
if ( componentPropertyStyle.doCascade( action ) ) {
cascadeProperty(
action,
cascadePoint,
eventSource,
componentPathStackDepth + 1,
parent,
children[i],
types[i],
@ -279,10 +303,13 @@ private void cascadeComponent(
);
}
}
componentPathStackDepth--;
}
private void cascadeAssociation(
private static void cascadeAssociation(
final CascadingAction action,
final CascadePoint cascadePoint,
final EventSource eventSource,
final int componentPathStackDepth,
final Object parent,
final Object child,
final Type type,
@ -290,17 +317,31 @@ private void cascadeAssociation(
final Object anything,
final boolean isCascadeDeleteEnabled) {
if ( type.isEntityType() || type.isAnyType() ) {
cascadeToOne( parent, child, type, style, anything, isCascadeDeleteEnabled );
cascadeToOne( action, eventSource, parent, child, type, style, anything, isCascadeDeleteEnabled );
}
else if ( type.isCollectionType() ) {
cascadeCollection( parent, child, style, anything, (CollectionType) type );
cascadeCollection(
action,
cascadePoint,
eventSource,
componentPathStackDepth,
parent,
child,
style,
anything,
(CollectionType) type
);
}
}
/**
* Cascade an action to a collection
*/
private void cascadeCollection(
private static void cascadeCollection(
final CascadingAction action,
final CascadePoint cascadePoint,
final EventSource eventSource,
final int componentPathStackDepth,
final Object parent,
final Object child,
final CascadeStyle style,
@ -309,14 +350,18 @@ private void cascadeCollection(
final CollectionPersister persister = eventSource.getFactory().getCollectionPersister( type.getRole() );
final Type elemType = persister.getElementType();
final CascadePoint originalCascadePoint = cascadePoint;
if ( cascadePoint == CascadePoint.AFTER_INSERT_BEFORE_DELETE) {
cascadePoint = CascadePoint.AFTER_INSERT_BEFORE_DELETE_VIA_COLLECTION;
CascadePoint elementsCascadePoint = cascadePoint;
if ( cascadePoint == CascadePoint.AFTER_INSERT_BEFORE_DELETE ) {
elementsCascadePoint = CascadePoint.AFTER_INSERT_BEFORE_DELETE_VIA_COLLECTION;
}
//cascade to current collection elements
if ( elemType.isEntityType() || elemType.isAnyType() || elemType.isComponentType() ) {
cascadeCollectionElements(
action,
elementsCascadePoint,
eventSource,
componentPathStackDepth,
parent,
child,
type,
@ -326,14 +371,14 @@ private void cascadeCollection(
persister.isCascadeDeleteEnabled()
);
}
cascadePoint = originalCascadePoint;
}
/**
* Cascade an action to a to-one association or any type
*/
private void cascadeToOne(
private static void cascadeToOne(
final CascadingAction action,
final EventSource eventSource,
final Object parent,
final Object child,
final Type type,
@ -358,7 +403,11 @@ private void cascadeToOne(
/**
* Cascade to the collection elements
*/
private void cascadeCollectionElements(
private static void cascadeCollectionElements(
final CascadingAction action,
final CascadePoint cascadePoint,
final EventSource eventSource,
final int componentPathStackDepth,
final Object parent,
final Object child,
final CollectionType collectionType,
@ -377,6 +426,10 @@ private void cascadeCollectionElements(
final Iterator itr = action.getCascadableChildrenIterator( eventSource, collectionType, child );
while ( itr.hasNext() ) {
cascadeProperty(
action,
cascadePoint,
eventSource,
componentPathStackDepth,
parent,
itr.next(),
elemType,
@ -407,7 +460,7 @@ private void cascadeCollectionElements(
// 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 );
deleteOrphans( eventSource, entityName, (PersistentCollection) child );
if ( traceEnabled ) {
LOG.tracev( "Done deleting orphans for collection: {0}", collectionType.getRole() );
@ -418,7 +471,7 @@ private void cascadeCollectionElements(
/**
* Delete any entities that were removed from the collection
*/
private void deleteOrphans(String entityName, PersistentCollection pc) throws HibernateException {
private static void deleteOrphans(EventSource eventSource, String entityName, PersistentCollection pc) throws HibernateException {
//TODO: suck this logic into the collection!
final Collection orphans;
if ( pc.wasInitialized() ) {

View File

@ -164,7 +164,7 @@ private void cascadeOnFlush(EventSource session, EntityPersister persister, Obje
throws HibernateException {
session.getPersistenceContext().incrementCascadeLevel();
try {
new Cascade( getCascadingAction(), CascadePoint.BEFORE_FLUSH, session ).cascade( persister, object, anything );
Cascade.cascade( getCascadingAction(), CascadePoint.BEFORE_FLUSH, session, persister, object, anything );
}
finally {
session.getPersistenceContext().decrementCascadeLevel();

View File

@ -429,7 +429,10 @@ protected void cascadeBeforeSave(
// cascade-save to many-to-one BEFORE the parent is saved
source.getPersistenceContext().incrementCascadeLevel();
try {
new Cascade( getCascadeAction(), CascadePoint.BEFORE_INSERT_AFTER_DELETE, source ).cascade(
Cascade.cascade(
getCascadeAction(),
CascadePoint.BEFORE_INSERT_AFTER_DELETE,
source,
persister,
entity,
anything
@ -457,7 +460,10 @@ protected void cascadeAfterSave(
// cascade-save to collections AFTER the collection owner was saved
source.getPersistenceContext().incrementCascadeLevel();
try {
new Cascade( getCascadeAction(), CascadePoint.AFTER_INSERT_BEFORE_DELETE, source ).cascade(
Cascade.cascade(
getCascadeAction(),
CascadePoint.AFTER_INSERT_BEFORE_DELETE,
source,
persister,
entity,
anything

View File

@ -350,7 +350,10 @@ protected void cascadeBeforeDelete(
session.getPersistenceContext().incrementCascadeLevel();
try {
// cascade-delete to collections BEFORE the collection owner is deleted
new Cascade( CascadingActions.DELETE, CascadePoint.AFTER_INSERT_BEFORE_DELETE, session ).cascade(
Cascade.cascade(
CascadingActions.DELETE,
CascadePoint.AFTER_INSERT_BEFORE_DELETE,
session,
persister,
entity,
transientEntities
@ -373,7 +376,10 @@ protected void cascadeAfterDelete(
session.getPersistenceContext().incrementCascadeLevel();
try {
// cascade-delete to many-to-one AFTER the parent was deleted
new Cascade( CascadingActions.DELETE, CascadePoint.BEFORE_INSERT_AFTER_DELETE, session ).cascade(
Cascade.cascade(
CascadingActions.DELETE,
CascadePoint.BEFORE_INSERT_AFTER_DELETE,
session,
persister,
entity,
transientEntities

View File

@ -145,6 +145,6 @@ protected void doEvict(
// This is now handled by removeEntity()
//session.getPersistenceContext().removeDatabaseSnapshot(key);
new Cascade( CascadingActions.EVICT, CascadePoint.AFTER_EVICT, session ).cascade( persister, object );
Cascade.cascade( CascadingActions.EVICT, CascadePoint.AFTER_EVICT, session, persister, object );
}
}

View File

@ -103,7 +103,10 @@ private void cascadeOnLock(LockEvent event, EntityPersister persister, Object en
EventSource source = event.getSession();
source.getPersistenceContext().incrementCascadeLevel();
try {
new Cascade( CascadingActions.LOCK, CascadePoint.AFTER_LOCK, source).cascade(
Cascade.cascade(
CascadingActions.LOCK,
CascadePoint.AFTER_LOCK,
source,
persister,
entity,
event.getLockOptions()

View File

@ -471,7 +471,10 @@ protected void cascadeOnMerge(
) {
source.getPersistenceContext().incrementCascadeLevel();
try {
new Cascade( getCascadeAction(), CascadePoint.BEFORE_MERGE, source ).cascade(
Cascade.cascade(
getCascadeAction(),
CascadePoint.BEFORE_MERGE,
source,
persister,
entity,
copyCache

View File

@ -135,7 +135,10 @@ public void onRefresh(RefreshEvent event, Map refreshedAlready) {
// cascade the refresh prior to refreshing this entity
refreshedAlready.put( object, object );
new Cascade( CascadingActions.REFRESH, CascadePoint.BEFORE_REFRESH, source ).cascade(
Cascade.cascade(
CascadingActions.REFRESH,
CascadePoint.BEFORE_REFRESH,
source,
persister,
object,
refreshedAlready

View File

@ -222,7 +222,10 @@ private void cascadeAfterReplicate(
EventSource source) {
source.getPersistenceContext().incrementCascadeLevel();
try {
new Cascade( CascadingActions.REPLICATE, CascadePoint.AFTER_UPDATE, source ).cascade(
Cascade.cascade(
CascadingActions.REPLICATE,
CascadePoint.AFTER_UPDATE,
source,
persister,
entity,
replicationMode

View File

@ -372,7 +372,7 @@ private void cascadeOnUpdate(SaveOrUpdateEvent event, EntityPersister persister,
final EventSource source = event.getSession();
source.getPersistenceContext().incrementCascadeLevel();
try {
new Cascade( CascadingActions.SAVE_UPDATE, CascadePoint.AFTER_UPDATE, source ).cascade( persister, entity );
Cascade.cascade( CascadingActions.SAVE_UPDATE, CascadePoint.AFTER_UPDATE, source, persister, entity );
}
finally {
source.getPersistenceContext().decrementCascadeLevel();