我们知道merge方法会更新session缓存中已存在的对象,
hibernate 架构中对于对象执行save,update,delete,都是基于观察者模式实现,每个操作都会触发相应的观察者执行相应操作,merge方法会先促发MergeEvent,
public Object merge(String entityName, Object object) throws HibernateException { return fireMerge( new MergeEvent( entityName, object, this ) ); }
private Object fireMerge(MergeEvent event) { //方法里面主要判断session 是否已关闭 errorIfClosed(); //尝试注册jta事物 checkTransactionSynchStatus(); checkNoUnresolvedActionsBeforeOperation(); for ( MergeEventListener listener : listeners( EventType.MERGE ) ) { //merge执行观察者方法,基于事件监听方式方便以后扩展,我们可以对自己感兴趣的事件注册实注册观察者 listener.onMerge( event ); } checkNoUnresolvedActionsAfterOperation(); return event.getResult(); }merge 主要方法实现
public void onMerge(MergeEvent event, Map copiedAlready) throws HibernateException { final EventCache copyCache = ( EventCache ) copiedAlready; //source其实就是SessionImpl final EventSource source = event.getSession(); final Object original = event.getOriginal(); if ( original != null ) { final Object entity; //是否是hiernate 代理对象 i f ( original instanceof HibernateProxy ) { LazyInitializer li = ( (HibernateProxy) original ).getHibernateLazyInitializer(); //是否没有初始化原对象 if ( li.isUninitialized() ) { LOG.trace( "Ignoring uninitialized proxy" ); event.setResult( source.load( li.getEntityName(), li.getIdentifier() ) ); return; //EARLY EXIT! } else { //从数据库查询真实对象 entity = li.getImplementation(); } } else { entity = original; } if ( copyCache.containsKey( entity ) && ( copyCache.isOperatedOn( entity ) ) ) { LOG.trace( "Already in merge process" ); event.setResult( entity ); } else { if ( copyCache.containsKey( entity ) ) { LOG.trace( "Already in copyCache; setting in merge process" ); copyCache.setOperatedOn( entity, true ); } event.setEntity( entity ); EntityState entityState = null; //从session缓存找是否存在当前对象 EntityEntry entry = source.getPersistenceContext().getEntry( entity ); if ( entry == null ) { EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity ); Serializable id = persister.getIdentifier( entity, source ); if ( id != null ) { final EntityKey key = source.generateEntityKey( id, persister ); final Object managedEntity = source.getPersistenceContext().getEntity( key ); entry = source.getPersistenceContext().getEntry( managedEntity ); if ( entry != null ) { //假如对象有Id而且根据Id从session缓存找到那就是托管状态 entityState = EntityState.DETACHED; } } } if ( entityState == null ) { //缓存找到,数据库也有那就是持久化 //只要id有值且不是删除的,状态就是托管 entityState = getEntityState( entity, event.getEntityName(), entry, source ); } switch (entityState) { case DETACHED: entityIsDetached(event, copyCache); break; case TRANSIENT: entityIsTransient(event, copyCache); break; case PERSISTENT: entityIsPersistent(event, copyCache); break; default: //DELETED throw new ObjectDeletedException( "deleted instance passed to merge", null, getLoggableName( event.getEntityName(), entity ) ); } } } }hibernate 真正执行删除啊更新等要调session的flush,SessionImpl 里面有个ActionQueue,这个对象里面存放要跟新,删除,保存,的行为集合。flush方法会填充这些集合。接着执行。