Package org.hibernate.action.internal

Source Code of org.hibernate.action.internal.EntityInsertAction

/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors.  All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA  02110-1301  USA
*/
package org.hibernate.action.internal;

import java.io.Serializable;

import org.hibernate.AssertionFailure;
import org.hibernate.HibernateException;
import org.hibernate.cache.spi.CacheKey;
import org.hibernate.cache.spi.entry.CacheEntry;
import org.hibernate.engine.internal.Versioning;
import org.hibernate.engine.spi.EntityEntry;
import org.hibernate.engine.spi.EntityKey;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.event.service.spi.EventListenerGroup;
import org.hibernate.event.spi.EventType;
import org.hibernate.event.spi.PostInsertEvent;
import org.hibernate.event.spi.PostInsertEventListener;
import org.hibernate.event.spi.PreInsertEvent;
import org.hibernate.event.spi.PreInsertEventListener;
import org.hibernate.persister.entity.EntityPersister;

public final class EntityInsertAction extends AbstractEntityInsertAction {

  private Object version;
  private Object cacheEntry;

  public EntityInsertAction(
      Serializable id,
      Object[] state,
      Object instance,
      Object version,
      EntityPersister persister,
      boolean isVersionIncrementDisabled,
      SessionImplementor session) throws HibernateException {
    super( id, state, instance, isVersionIncrementDisabled, persister, session );
    this.version = version;
  }

  @Override
  public boolean isEarlyInsert() {
    return false;
  }

  @Override
  protected EntityKey getEntityKey() {
    return getSession().generateEntityKey( getId(), getPersister() );
  }

  @Override
  public void execute() throws HibernateException {
    nullifyTransientReferencesIfNotAlready();

    EntityPersister persister = getPersister();
    SessionImplementor session = getSession();
    Object instance = getInstance();
    Serializable id = getId();

    boolean veto = preInsert();

    // Don't need to lock the cache here, since if someone
    // else inserted the same pk first, the insert would fail

    if ( !veto ) {
     
      persister.insert( id, getState(), instance, session );
   
      EntityEntry entry = session.getPersistenceContext().getEntry( instance );
      if ( entry == null ) {
        throw new AssertionFailure( "possible non-threadsafe access to session" );
      }
     
      entry.postInsert( getState() );
 
      if ( persister.hasInsertGeneratedProperties() ) {
        persister.processInsertGeneratedProperties( id, instance, getState(), session );
        if ( persister.isVersionPropertyGenerated() ) {
          version = Versioning.getVersion( getState(), persister );
        }
        entry.postUpdate(instance, getState(), version);
      }

      getSession().getPersistenceContext().registerInsertedKey( getPersister(), getId() );
    }

    final SessionFactoryImplementor factory = getSession().getFactory();

    if ( isCachePutEnabled( persister, session ) ) {
     
      CacheEntry ce = new CacheEntry(
          getState(),
          persister,
          persister.hasUninitializedLazyProperties( instance ),
          version,
          session,
          instance
        );
     
      cacheEntry = persister.getCacheEntryStructure().structure(ce);
      final CacheKey ck = session.generateCacheKey( id, persister.getIdentifierType(), persister.getRootEntityName() );
      boolean put = persister.getCacheAccessStrategy().insert( ck, cacheEntry, version );
     
      if ( put && factory.getStatistics().isStatisticsEnabled() ) {
        factory.getStatisticsImplementor().secondLevelCachePut( getPersister().getCacheAccessStrategy().getRegion().getName() );
      }
    }

    handleNaturalIdPostSaveNotifications();

    postInsert();

    if ( factory.getStatistics().isStatisticsEnabled() && !veto ) {
      factory.getStatisticsImplementor()
          .insertEntity( getPersister().getEntityName() );
    }

    markExecuted();
  }

  private void postInsert() {
    EventListenerGroup<PostInsertEventListener> listenerGroup = listenerGroup( EventType.POST_INSERT );
    if ( listenerGroup.isEmpty() ) {
      return;
    }
    final PostInsertEvent event = new PostInsertEvent(
        getInstance(),
        getId(),
        getState(),
        getPersister(),
        eventSource()
    );
    for ( PostInsertEventListener listener : listenerGroup.listeners() ) {
      listener.onPostInsert( event );
    }
  }

  private void postCommitInsert() {
    EventListenerGroup<PostInsertEventListener> listenerGroup = listenerGroup( EventType.POST_COMMIT_INSERT );
    if ( listenerGroup.isEmpty() ) {
      return;
    }
    final PostInsertEvent event = new PostInsertEvent(
        getInstance(),
        getId(),
        getState(),
        getPersister(),
        eventSource()
    );
    for ( PostInsertEventListener listener : listenerGroup.listeners() ) {
      listener.onPostInsert( event );
    }
  }

  private boolean preInsert() {
    boolean veto = false;

    EventListenerGroup<PreInsertEventListener> listenerGroup = listenerGroup( EventType.PRE_INSERT );
    if ( listenerGroup.isEmpty() ) {
      return veto;
    }
    final PreInsertEvent event = new PreInsertEvent( getInstance(), getId(), getState(), getPersister(), eventSource() );
    for ( PreInsertEventListener listener : listenerGroup.listeners() ) {
      veto |= listener.onPreInsert( event );
    }
    return veto;
  }

  @Override
  public void doAfterTransactionCompletion(boolean success, SessionImplementor session) throws HibernateException {
    EntityPersister persister = getPersister();
    if ( success && isCachePutEnabled( persister, getSession() ) ) {
      final CacheKey ck = getSession().generateCacheKey( getId(), persister.getIdentifierType(), persister.getRootEntityName() );
      boolean put = persister.getCacheAccessStrategy().afterInsert( ck, cacheEntry, version );
     
      if ( put && getSession().getFactory().getStatistics().isStatisticsEnabled() ) {
        getSession().getFactory().getStatisticsImplementor()
            .secondLevelCachePut( getPersister().getCacheAccessStrategy().getRegion().getName() );
      }
    }
    postCommitInsert();
  }

  @Override
  protected boolean hasPostCommitEventListeners() {
    return ! listenerGroup( EventType.POST_COMMIT_INSERT ).isEmpty();
  }
 
  private boolean isCachePutEnabled(EntityPersister persister, SessionImplementor session) {
    return persister.hasCache()
        && !persister.isCacheInvalidationRequired()
        && session.getCacheMode().isPutEnabled();
  }

}
TOP

Related Classes of org.hibernate.action.internal.EntityInsertAction

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.