hiberntae 源码分析之merge方法

我们知道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方法会填充这些集合。接着执行。

猜你喜欢

转载自xuyunti.iteye.com/blog/2226704
今日推荐