⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 defaultsaveorupdateeventlistener.java

📁 一个Java持久层类库
💻 JAVA
字号:
// $Id: DefaultSaveOrUpdateEventListener.java 10948 2006-12-07 21:53:10Z steve.ebersole@jboss.com $package org.hibernate.event.def;import java.io.Serializable;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.hibernate.AssertionFailure;import org.hibernate.EntityMode;import org.hibernate.HibernateException;import org.hibernate.LockMode;import org.hibernate.PersistentObjectException;import org.hibernate.TransientObjectException;import org.hibernate.classic.Lifecycle;import org.hibernate.engine.Cascade;import org.hibernate.engine.CascadingAction;import org.hibernate.engine.EntityEntry;import org.hibernate.engine.EntityKey;import org.hibernate.engine.SessionFactoryImplementor;import org.hibernate.engine.SessionImplementor;import org.hibernate.engine.Status;import org.hibernate.event.EventSource;import org.hibernate.event.SaveOrUpdateEvent;import org.hibernate.event.SaveOrUpdateEventListener;import org.hibernate.persister.entity.EntityPersister;import org.hibernate.pretty.MessageHelper;import org.hibernate.proxy.HibernateProxy;/** * Defines the default listener used by Hibernate for handling save-update * events. * * @author Steve Ebersole * @author Gavin King */public class DefaultSaveOrUpdateEventListener extends AbstractSaveEventListener implements SaveOrUpdateEventListener {	private static final Logger log = LoggerFactory.getLogger( DefaultSaveOrUpdateEventListener.class );	/**	 * Handle the given update event.	 *	 * @param event The update event to be handled.	 */	public void onSaveOrUpdate(SaveOrUpdateEvent event) {		final SessionImplementor source = event.getSession();		final Object object = event.getObject();		final Serializable requestedId = event.getRequestedId();		if ( requestedId != null ) {			//assign the requested id to the proxy, *before*			//reassociating the proxy			if ( object instanceof HibernateProxy ) {				( ( HibernateProxy ) object ).getHibernateLazyInitializer().setIdentifier( requestedId );			}		}		if ( reassociateIfUninitializedProxy( object, source ) ) {			log.trace( "reassociated uninitialized proxy" );			// an uninitialized proxy, noop, don't even need to			// return an id, since it is never a save()		}		else {			//initialize properties of the event:			final Object entity = source.getPersistenceContext().unproxyAndReassociate( object );			event.setEntity( entity );			event.setEntry( source.getPersistenceContext().getEntry( entity ) );			//return the id in the event object			event.setResultId( performSaveOrUpdate( event ) );		}	}	protected boolean reassociateIfUninitializedProxy(Object object, SessionImplementor source) {		return source.getPersistenceContext().reassociateIfUninitializedProxy( object );	}	protected Serializable performSaveOrUpdate(SaveOrUpdateEvent event) {		int entityState = getEntityState(				event.getEntity(),				event.getEntityName(),				event.getEntry(),				event.getSession()		);		switch ( entityState ) {			case DETACHED:				entityIsDetached( event );				return null;			case PERSISTENT:				return entityIsPersistent( event );			default: //TRANSIENT or DELETED				return entityIsTransient( event );		}	}	protected Serializable entityIsPersistent(SaveOrUpdateEvent event) throws HibernateException {		log.trace( "ignoring persistent instance" );		EntityEntry entityEntry = event.getEntry();		if ( entityEntry == null ) {			throw new AssertionFailure( "entity was transient or detached" );		}		else {			if ( entityEntry.getStatus() == Status.DELETED ) {				throw new AssertionFailure( "entity was deleted" );			}			final SessionFactoryImplementor factory = event.getSession().getFactory();			Serializable requestedId = event.getRequestedId();			Serializable savedId;			if ( requestedId == null ) {				savedId = entityEntry.getId();			}			else {				final boolean isEqual = !entityEntry.getPersister().getIdentifierType()						.isEqual( requestedId, entityEntry.getId(), event.getSession().getEntityMode(), factory );				if ( isEqual ) {					throw new PersistentObjectException(							"object passed to save() was already persistent: " +									MessageHelper.infoString( entityEntry.getPersister(), requestedId, factory )					);				}				savedId = requestedId;			}			if ( log.isTraceEnabled() ) {				log.trace(						"object already associated with session: " +								MessageHelper.infoString( entityEntry.getPersister(), savedId, factory )				);			}			return savedId;		}	}	/**	 * The given save-update event named a transient entity.	 * <p/>	 * Here, we will perform the save processing.	 *	 * @param event The save event to be handled.	 *	 * @return The entity's identifier after saving.	 */	protected Serializable entityIsTransient(SaveOrUpdateEvent event) {		log.trace( "saving transient instance" );		final EventSource source = event.getSession();		EntityEntry entityEntry = event.getEntry();		if ( entityEntry != null ) {			if ( entityEntry.getStatus() == Status.DELETED ) {				source.forceFlush( entityEntry );			}			else {				throw new AssertionFailure( "entity was persistent" );			}		}		Serializable id = saveWithGeneratedOrRequestedId( event );		source.getPersistenceContext().reassociateProxy( event.getObject(), id );		return id;	}	/**	 * Save the transient instance, assigning the right identifier	 *	 * @param event The initiating event.	 *	 * @return The entity's identifier value after saving.	 */	protected Serializable saveWithGeneratedOrRequestedId(SaveOrUpdateEvent event) {		return saveWithGeneratedId(				event.getEntity(),				event.getEntityName(),				null,				event.getSession(),				true		);	}	/**	 * The given save-update event named a detached entity.	 * <p/>	 * Here, we will perform the update processing.	 *	 * @param event The update event to be handled.	 */	protected void entityIsDetached(SaveOrUpdateEvent event) {		log.trace( "updating detached instance" );		if ( event.getSession().getPersistenceContext().isEntryFor( event.getEntity() ) ) {			//TODO: assertion only, could be optimized away			throw new AssertionFailure( "entity was persistent" );		}		Object entity = event.getEntity();		EntityPersister persister = event.getSession().getEntityPersister( event.getEntityName(), entity );		event.setRequestedId(				getUpdateId(						entity, persister, event.getRequestedId(), event.getSession().getEntityMode()				)		);		performUpdate( event, entity, persister );	}	/**	 * Determine the id to use for updating.	 *	 * @param entity The entity.	 * @param persister The entity persister	 * @param requestedId The requested identifier	 * @param entityMode The entity mode.	 *	 * @return The id.	 *	 * @throws TransientObjectException If the entity is considered transient.	 */	protected Serializable getUpdateId(			Object entity,			EntityPersister persister,			Serializable requestedId,			EntityMode entityMode) {		// use the id assigned to the instance		Serializable id = persister.getIdentifier( entity, entityMode );		if ( id == null ) {			// assume this is a newly instantiated transient object			// which should be saved rather than updated			throw new TransientObjectException(					"The given object has a null identifier: " +							persister.getEntityName()			);		}		else {			return id;		}	}	protected void performUpdate(			SaveOrUpdateEvent event,			Object entity,			EntityPersister persister) throws HibernateException {		if ( !persister.isMutable() ) {			log.trace( "immutable instance passed to doUpdate(), locking" );			reassociate( event, entity, event.getRequestedId(), persister );		}		else {			if ( log.isTraceEnabled() ) {				log.trace(						"updating " +								MessageHelper.infoString(										persister, event.getRequestedId(), event.getSession().getFactory()								)				);			}			final EventSource source = event.getSession();			EntityKey key = new EntityKey( event.getRequestedId(), persister, source.getEntityMode() );			source.getPersistenceContext().checkUniqueness( key, entity );			if ( invokeUpdateLifecycle( entity, persister, source ) ) {				reassociate( event, event.getObject(), event.getRequestedId(), persister );				return;			}			// this is a transient object with existing persistent state not loaded by the session			new OnUpdateVisitor( source, event.getRequestedId(), entity ).process( entity, persister );			//TODO: put this stuff back in to read snapshot from			//      the second-level cache (needs some extra work)			/*Object[] cachedState = null;			if ( persister.hasCache() ) {				CacheEntry entry = (CacheEntry) persister.getCache()						.get( event.getRequestedId(), source.getTimestamp() );			    cachedState = entry==null ?			    		null :			    		entry.getState(); //TODO: half-assemble this stuff			}*/			source.getPersistenceContext().addEntity(					entity,					Status.MANAGED,					null, //cachedState,					key,					persister.getVersion( entity, source.getEntityMode() ),					LockMode.NONE,					true,					persister,					false,					true //assume true, since we don't really know, and it doesn't matter			);			persister.afterReassociate( entity, source );			if ( log.isTraceEnabled() ) {				log.trace(						"updating " +								MessageHelper.infoString( persister, event.getRequestedId(), source.getFactory() )				);			}			cascadeOnUpdate( event, persister, entity );		}	}	protected boolean invokeUpdateLifecycle(Object entity, EntityPersister persister, EventSource source) {		if ( persister.implementsLifecycle( source.getEntityMode() ) ) {			log.debug( "calling onUpdate()" );			if ( ( ( Lifecycle ) entity ).onUpdate( source ) ) {				log.debug( "update vetoed by onUpdate()" );				return true;			}		}		return false;	}	/**	 * Handles the calls needed to perform cascades as part of an update request	 * for the given entity.	 *	 * @param event The event currently being processed.	 * @param persister The defined persister for the entity being updated.	 * @param entity The entity being updated.	 */	private void cascadeOnUpdate(SaveOrUpdateEvent event, EntityPersister persister, Object entity) {		EventSource source = event.getSession();		source.getPersistenceContext().incrementCascadeLevel();		try {			new Cascade( CascadingAction.SAVE_UPDATE, Cascade.AFTER_UPDATE, source )					.cascade( persister, entity );		}		finally {			source.getPersistenceContext().decrementCascadeLevel();		}	}	protected CascadingAction getCascadeAction() {		return CascadingAction.SAVE_UPDATE;	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -