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.HibernateException;
   30   import org.hibernate.AssertionFailure;
   31   import org.hibernate.engine.SessionImplementor;
   32   import org.hibernate.engine.EntityKey;
   33   import org.hibernate.event.PostInsertEvent;
   34   import org.hibernate.event.PostInsertEventListener;
   35   import org.hibernate.event.PreInsertEvent;
   36   import org.hibernate.event.PreInsertEventListener;
   37   import org.hibernate.event.EventSource;
   38   import org.hibernate.persister.entity.EntityPersister;
   39   
   40   public final class EntityIdentityInsertAction extends EntityAction {
   41   	private final Object[] state;
   42   	private final boolean isDelayed;
   43   	private final EntityKey delayedEntityKey;
   44   	//private CacheEntry cacheEntry;
   45   	private Serializable generatedId;
   46   
   47   	public EntityIdentityInsertAction(
   48   			Object[] state,
   49   	        Object instance,
   50   	        EntityPersister persister,
   51   	        SessionImplementor session,
   52   	        boolean isDelayed) throws HibernateException {
   53   		super( session, null, instance, persister );
   54   		this.state = state;
   55   		this.isDelayed = isDelayed;
   56   		delayedEntityKey = isDelayed ? generateDelayedEntityKey() : null;
   57   	}
   58   
   59   	public void execute() throws HibernateException {
   60   		
   61   		final EntityPersister persister = getPersister();
   62   		final SessionImplementor session = getSession();
   63   		final Object instance = getInstance();
   64   		
   65   		boolean veto = preInsert();
   66   
   67   		// Don't need to lock the cache here, since if someone
   68   		// else inserted the same pk first, the insert would fail
   69   
   70   		if ( !veto ) {
   71   			generatedId = persister.insert( state, instance, session );
   72   			if ( persister.hasInsertGeneratedProperties() ) {
   73   				persister.processInsertGeneratedProperties( generatedId, instance, state, session );
   74   			}
   75   			//need to do that here rather than in the save event listener to let
   76   			//the post insert events to have a id-filled entity when IDENTITY is used (EJB3)
   77   			persister.setIdentifier( instance, generatedId, session.getEntityMode() );
   78   		}
   79   
   80   
   81   		//TODO: this bit actually has to be called after all cascades!
   82   		//      but since identity insert is called *synchronously*,
   83   		//      instead of asynchronously as other actions, it isn't
   84   		/*if ( persister.hasCache() && !persister.isCacheInvalidationRequired() ) {
   85   			cacheEntry = new CacheEntry(object, persister, session);
   86   			persister.getCache().insert(generatedId, cacheEntry);
   87   		}*/
   88   		
   89   		postInsert();
   90   
   91   		if ( session.getFactory().getStatistics().isStatisticsEnabled() && !veto ) {
   92   			session.getFactory().getStatisticsImplementor()
   93   					.insertEntity( getPersister().getEntityName() );
   94   		}
   95   
   96   	}
   97   
   98   	private void postInsert() {
   99   		if ( isDelayed ) {
  100   			getSession().getPersistenceContext().replaceDelayedEntityIdentityInsertKeys( delayedEntityKey, generatedId );
  101   		}
  102   		PostInsertEventListener[] postListeners = getSession().getListeners()
  103   				.getPostInsertEventListeners();
  104   		if (postListeners.length>0) {
  105   			PostInsertEvent postEvent = new PostInsertEvent(
  106   					getInstance(),
  107   					generatedId,
  108   					state,
  109   					getPersister(),
  110   					(EventSource) getSession()
  111   			);
  112   			for ( int i = 0; i < postListeners.length; i++ ) {
  113   				postListeners[i].onPostInsert(postEvent);
  114   			}
  115   		}
  116   	}
  117   
  118   	private void postCommitInsert() {
  119   		PostInsertEventListener[] postListeners = getSession().getListeners()
  120   				.getPostCommitInsertEventListeners();
  121   		if (postListeners.length>0) {
  122   			PostInsertEvent postEvent = new PostInsertEvent(
  123   					getInstance(),
  124   					generatedId,
  125   					state,
  126   					getPersister(),
  127   					(EventSource) getSession() 
  128   			);
  129   			for ( int i = 0; i < postListeners.length; i++ ) {
  130   				postListeners[i].onPostInsert(postEvent);
  131   			}
  132   		}
  133   	}
  134   
  135   	private boolean preInsert() {
  136   		PreInsertEventListener[] preListeners = getSession().getListeners()
  137   				.getPreInsertEventListeners();
  138   		boolean veto = false;
  139   		if (preListeners.length>0) {
  140   			PreInsertEvent preEvent = new PreInsertEvent( getInstance(), null, state, getPersister(), (EventSource)getSession() );
  141   			for ( int i = 0; i < preListeners.length; i++ ) {
  142   				veto = preListeners[i].onPreInsert(preEvent) || veto;
  143   			}
  144   		}
  145   		return veto;
  146   	}
  147   
  148   	//Make 100% certain that this is called before any subsequent ScheduledUpdate.afterTransactionCompletion()!!
  149   	public void afterTransactionCompletion(boolean success) throws HibernateException {
  150   		//TODO: reenable if we also fix the above todo
  151   		/*EntityPersister persister = getEntityPersister();
  152   		if ( success && persister.hasCache() && !persister.isCacheInvalidationRequired() ) {
  153   			persister.getCache().afterInsert( getGeneratedId(), cacheEntry );
  154   		}*/
  155   		postCommitInsert();
  156   	}
  157   
  158   	public boolean hasAfterTransactionCompletion() {
  159   		//TODO: simply remove this override
  160   		//      if we fix the above todos
  161   		return hasPostCommitEventListeners();
  162   	}
  163   
  164   	protected boolean hasPostCommitEventListeners() {
  165   		return getSession().getListeners().getPostCommitInsertEventListeners().length>0;
  166   	}
  167   	
  168   	public final Serializable getGeneratedId() {
  169   		return generatedId;
  170   	}
  171   
  172   	public EntityKey getDelayedEntityKey() {
  173   		return delayedEntityKey;
  174   	}
  175   
  176   	private synchronized EntityKey generateDelayedEntityKey() {
  177   		if ( !isDelayed ) {
  178   			throw new AssertionFailure( "cannot request delayed entity-key for non-delayed post-insert-id generation" );
  179   		}
  180   		return new EntityKey( new DelayedPostInsertIdentifier(), getPersister(), getSession().getEntityMode() );
  181   	}
  182   }

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