Save This Page
Home » hibernate-distribution-3.3.1.GA-dist » org.hibernate » action » [javadoc | source]
    1   /*
    2    * Hibernate, Relational Persistence for Idiomatic Java
    3    *
    4    * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
    5    * indicated by the @author tags or express copyright attribution
    6    * statements applied by the authors.  All third-party contributions are
    7    * distributed under license by Red Hat Middleware LLC.
    8    *
    9    * This copyrighted material is made available to anyone wishing to use, modify,
   10    * copy, or redistribute it subject to the terms and conditions of the GNU
   11    * Lesser General Public License, as published by the Free Software Foundation.
   12    *
   13    * This program is distributed in the hope that it will be useful,
   14    * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   15    * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
   16    * for more details.
   17    *
   18    * You should have received a copy of the GNU Lesser General Public License
   19    * along with this distribution; if not, write to:
   20    * Free Software Foundation, Inc.
   21    * 51 Franklin Street, Fifth Floor
   22    * Boston, MA  02110-1301  USA
   23    *
   24    */
   25   package org.hibernate.action;
   26   
   27   import java.io.Serializable;
   28   
   29   import org.hibernate.AssertionFailure;
   30   import org.hibernate.HibernateException;
   31   import org.hibernate.cache.CacheKey;
   32   import org.hibernate.cache.access.SoftLock;
   33   import org.hibernate.engine.EntityEntry;
   34   import org.hibernate.engine.EntityKey;
   35   import org.hibernate.engine.PersistenceContext;
   36   import org.hibernate.engine.SessionImplementor;
   37   import org.hibernate.event.PostDeleteEvent;
   38   import org.hibernate.event.PostDeleteEventListener;
   39   import org.hibernate.event.PreDeleteEvent;
   40   import org.hibernate.event.PreDeleteEventListener;
   41   import org.hibernate.event.EventSource;
   42   import org.hibernate.persister.entity.EntityPersister;
   43   
   44   public final class EntityDeleteAction extends EntityAction {
   45   
   46   	private final Object version;
   47   	private SoftLock lock;
   48   	private final boolean isCascadeDeleteEnabled;
   49   	private final Object[] state;
   50   
   51   	public EntityDeleteAction(
   52   			final Serializable id,
   53   	        final Object[] state,
   54   	        final Object version,
   55   	        final Object instance,
   56   	        final EntityPersister persister,
   57   	        final boolean isCascadeDeleteEnabled,
   58   	        final SessionImplementor session) {
   59   		super( session, id, instance, persister );
   60   		this.version = version;
   61   		this.isCascadeDeleteEnabled = isCascadeDeleteEnabled;
   62   		this.state = state;
   63   	}
   64   
   65   	public void execute() throws HibernateException {
   66   		Serializable id = getId();
   67   		EntityPersister persister = getPersister();
   68   		SessionImplementor session = getSession();
   69   		Object instance = getInstance();
   70   
   71   		boolean veto = preDelete();
   72   
   73   		Object version = this.version;
   74   		if ( persister.isVersionPropertyGenerated() ) {
   75   			// we need to grab the version value from the entity, otherwise
   76   			// we have issues with generated-version entities that may have
   77   			// multiple actions queued during the same flush
   78   			version = persister.getVersion( instance, session.getEntityMode() );
   79   		}
   80   
   81   		final CacheKey ck;
   82   		if ( persister.hasCache() ) {
   83   			ck = new CacheKey( 
   84   					id, 
   85   					persister.getIdentifierType(), 
   86   					persister.getRootEntityName(), 
   87   					session.getEntityMode(), 
   88   					session.getFactory() 
   89   				);
   90   			lock = persister.getCacheAccessStrategy().lockItem( ck, version );
   91   		}
   92   		else {
   93   			ck = null;
   94   		}
   95   
   96   		if ( !isCascadeDeleteEnabled && !veto ) {
   97   			persister.delete( id, version, instance, session );
   98   		}
   99   		
  100   		//postDelete:
  101   		// After actually deleting a row, record the fact that the instance no longer 
  102   		// exists on the database (needed for identity-column key generation), and
  103   		// remove it from the session cache
  104   		final PersistenceContext persistenceContext = session.getPersistenceContext();
  105   		EntityEntry entry = persistenceContext.removeEntry( instance );
  106   		if ( entry == null ) {
  107   			throw new AssertionFailure( "possible nonthreadsafe access to session" );
  108   		}
  109   		entry.postDelete();
  110   
  111   		EntityKey key = new EntityKey( entry.getId(), entry.getPersister(), session.getEntityMode() );
  112   		persistenceContext.removeEntity(key);
  113   		persistenceContext.removeProxy(key);
  114   		
  115   		if ( persister.hasCache() ) persister.getCacheAccessStrategy().remove( ck );
  116   
  117   		postDelete();
  118   
  119   		if ( getSession().getFactory().getStatistics().isStatisticsEnabled() && !veto ) {
  120   			getSession().getFactory().getStatisticsImplementor()
  121   					.deleteEntity( getPersister().getEntityName() );
  122   		}
  123   	}
  124   
  125   	private boolean preDelete() {
  126   		PreDeleteEventListener[] preListeners = getSession().getListeners()
  127   				.getPreDeleteEventListeners();
  128   		boolean veto = false;
  129   		if (preListeners.length>0) {
  130   			PreDeleteEvent preEvent = new PreDeleteEvent( getInstance(), getId(), state, getPersister() ,(EventSource) getSession() );
  131   			for ( int i = 0; i < preListeners.length; i++ ) {
  132   				veto = preListeners[i].onPreDelete(preEvent) || veto;
  133   			}
  134   		}
  135   		return veto;
  136   	}
  137   
  138   	private void postDelete() {
  139   		PostDeleteEventListener[] postListeners = getSession().getListeners()
  140   				.getPostDeleteEventListeners();
  141   		if (postListeners.length>0) {
  142   			PostDeleteEvent postEvent = new PostDeleteEvent(
  143   					getInstance(),
  144   					getId(),
  145   					state,
  146   					getPersister(),
  147   					(EventSource) getSession() 
  148   			);
  149   			for ( int i = 0; i < postListeners.length; i++ ) {
  150   				postListeners[i].onPostDelete(postEvent);
  151   			}
  152   		}
  153   	}
  154   
  155   	private void postCommitDelete() {
  156   		PostDeleteEventListener[] postListeners = getSession().getListeners()
  157   				.getPostCommitDeleteEventListeners();
  158   		if (postListeners.length>0) {
  159   			PostDeleteEvent postEvent = new PostDeleteEvent(
  160   					getInstance(),
  161   					getId(),
  162   					state,
  163   					getPersister(),
  164   					(EventSource) getSession()
  165   			);
  166   			for ( int i = 0; i < postListeners.length; i++ ) {
  167   				postListeners[i].onPostDelete(postEvent);
  168   			}
  169   		}
  170   	}
  171   
  172   	public void afterTransactionCompletion(boolean success) throws HibernateException {
  173   		if ( getPersister().hasCache() ) {
  174   			final CacheKey ck = new CacheKey( 
  175   					getId(), 
  176   					getPersister().getIdentifierType(), 
  177   					getPersister().getRootEntityName(),
  178   					getSession().getEntityMode(), 
  179   					getSession().getFactory()
  180   				);
  181   			getPersister().getCacheAccessStrategy().unlockItem( ck, lock );
  182   		}
  183   		postCommitDelete();
  184   	}
  185   
  186   	protected boolean hasPostCommitEventListeners() {
  187   		return getSession().getListeners().getPostCommitDeleteEventListeners().length>0;
  188   	}
  189   
  190   }
  191   
  192   
  193   
  194   
  195   
  196   
  197   

Save This Page
Home » hibernate-distribution-3.3.1.GA-dist » org.hibernate » action » [javadoc | source]