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