📄 defaultsaveorupdateeventlistener.java
字号:
// $Id: DefaultSaveOrUpdateEventListener.java,v 1.4 2005/02/22 03:09:35 oneovthafew Exp $package org.hibernate.event.def;import java.io.Serializable;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.hibernate.AssertionFailure;import org.hibernate.HibernateException;import org.hibernate.LockMode;import org.hibernate.PersistentObjectException;import org.hibernate.TransientObjectException;import org.hibernate.EntityMode;import org.hibernate.classic.Lifecycle;import org.hibernate.engine.Cascades;import org.hibernate.engine.EntityEntry;import org.hibernate.engine.SessionFactoryImplementor;import org.hibernate.engine.Status;import org.hibernate.engine.Cascades.CascadingAction;import org.hibernate.event.SaveOrUpdateEvent;import org.hibernate.event.SaveOrUpdateEventListener;import org.hibernate.engine.SessionImplementor;import org.hibernate.persister.entity.EntityPersister;import org.hibernate.pretty.MessageHelper;import org.hibernate.proxy.HibernateProxy;/** * Defines the default update event listener used by hibernate for updating * transient entities in response to generated update events. * * @author Steve Ebersole, Gavin King */public class DefaultSaveOrUpdateEventListener extends AbstractSaveEventListener implements SaveOrUpdateEventListener { private static final Log log = LogFactory.getLog(DefaultSaveOrUpdateEventListener.class); /** * Handle the given update event. * * @param event The update event to be handled. * @throws HibernateException */ public Serializable onSaveOrUpdate(SaveOrUpdateEvent event) throws HibernateException { 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() return null; } //initialize properties of the event: final Object entity = source.getPersistenceContext().unproxyAndReassociate(object); event.setEntity(entity); event.setEntry( source.getPersistenceContext().getEntry(entity) ); return performSaveOrUpdate(event); } protected boolean reassociateIfUninitializedProxy(Object object, SessionImplementor source) { return source.getPersistenceContext().reassociateIfUninitializedProxy(object); } protected Serializable performSaveOrUpdate(SaveOrUpdateEvent event) { // use various roles to determine if the instance is // transient, persistent or detached: 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; } } /** * Handle the given save event. * * @param event The save event to be handled. * @throws HibernateException */ protected Serializable entityIsTransient(SaveOrUpdateEvent event) throws HibernateException { log.trace("saving transient instance"); final SessionImplementor 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 */ protected Serializable saveWithGeneratedOrRequestedId(SaveOrUpdateEvent event) { return saveWithGeneratedId( event.getEntity(), event.getEntityName(), null, event.getSession() ); } /** * Handle the given update event. * * @param event The update event to be handled. * @throws HibernateException */ protected void entityIsDetached(SaveOrUpdateEvent event) throws HibernateException { 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); } protected Serializable getUpdateId(Object entity, EntityPersister persister, Serializable requestedId, EntityMode entityMode) throws HibernateException { // 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 SessionImplementor source = event.getSession(); source.getPersistenceContext().checkUniqueness( event.getRequestedId(), persister, entity ); if ( persister.implementsLifecycle( source.getEntityMode() ) ) { log.debug( "calling onUpdate()" ); if ( ( ( Lifecycle ) entity ).onUpdate(source) ) { log.debug( "update vetoed by onUpdate()" ); 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() ).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, event.getRequestedId(), persister.getVersion( entity, source.getEntityMode() ), LockMode.NONE, true, persister, false ); persister.afterReassociate(entity, source); if ( log.isTraceEnabled() ) { log.trace( "updating " + MessageHelper.infoString( persister, event.getRequestedId(), source.getFactory() ) ); } cascadeOnUpdate(event, persister, entity); } } /** * 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) { SessionImplementor source = event.getSession(); source.getPersistenceContext().incrementCascadeLevel(); try { Cascades.cascade( source, persister, entity, Cascades.ACTION_SAVE_UPDATE, Cascades.CASCADE_AFTER_UPDATE ); } finally { source.getPersistenceContext().decrementCascadeLevel(); } } protected CascadingAction getCascadeAction() { return Cascades.ACTION_SAVE_UPDATE; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -