`

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方法会填充这些集合。接着执行。
分享到:
评论

相关推荐

    Merge Room 合并室内Unity合并房间游戏项目源码C#

    Merge Room 合并室内Unity合并房间游戏项目源码C# 支持Unity版本2021.3.20f1或更高 描述 Merge Room 是一款令人上瘾的手机游戏,玩家的任务是用物品填充房间。游戏的概念简单但具有挑战性,因为玩家必须将物体合并在...

    WinMerge阅读源码改动工具

    WinMerge,这款被誉为阅读源码改动的利器,是软件开发人员和版本控制爱好者不可或缺的工具之一。它以其直观易用的界面和强大的对比功能,使得查看和理解代码变更变得轻而易举。在本文中,我们将深入探讨WinMerge的...

    Hibernate中的merge使用详情解说

    在 Hibernate 中,merge 方法是非常重要的一个方法,它能够帮助开发者轻松地处理数据的更新和插入操作。那么,merge 方法到底如何工作的呢?下面,我们将对 merge 方法进行详细的解释。 首先,merge 方法是一个可以...

    Merge Balls 合并球 –高级 Unity 游戏项目源码C#

    Merge Balls 合并球 –高级 Unity 游戏项目源码C# 支持Unity版本5.6.5f1及以上 描述 射击并合并相同颜色的球直到它们爆炸,在这款台球风格的游戏中展示您的技能。 Merge Ballss 是一款简单但令人惊讶的令人上瘾的...

    merge的注意事项

    在探讨“merge的注意事项”这一主题时,我们深入解析Hibernate框架中merge操作的特性与应用场景,以及它与其他数据持久化方法的区别,特别是与saveOrUpdate函数的对比。这不仅有助于理解Hibernate的核心机制,还能...

    Araxis Merge v6.5/Araxis Merge 2017比对工具

    Araxis Merge是一款比对软件工具,不仅支持单个文件的比对,而且支持对两个文件夹的所有文件进行对比,并实时修改。用了蛮久感觉很好用,所以分享给大家。 里面给大家内嵌了Araxis Merge v6.5和Araxis Merge 2017两...

    Hibernate merge、update与saveOrUpdate方法的区别

    通过上述分析可以看出,`merge`、`update`和`saveOrUpdate`方法在处理实体对象时有不同的行为。选择合适的方法取决于具体的业务场景和需求。例如,在需要更新现有记录时,可以考虑使用`update`或`merge`方法;而在不...

    源码比较合并工具merge60

    merge60是一个Windows下的、开源的比较合并工具,它可以直观地显示比较结果,合并文件也比较容易。

    WinMerge WinMerge WinMerge

    WinMerge是一款强大的文本和文件比较工具,尤其在IT行业中,它是开发者和版本控制使用者的得力助手。这个软件能够帮助用户高效地对比不同版本的代码或者其他文本文件,从而快速定位和理解版本之间的差异。 首先,...

    winmerge代码比较工具

    虽然WinMerge和Beyond Compare在功能上有很多相似之处,如文件和文件夹的比较、合并操作等,但两者也有一些区别: - **价格**:Beyond Compare通常需要购买许可证,而WinMerge是免费的,无需注册码。 - **用户界面*...

    AraxisMerge绿色版

    Araxis Merge是一款备受推崇的文件比较工具,尤其在IT专业人士中广受欢迎。它以其强大的功能、易用性和高效性著称,被誉为最好用的比较工具。这个“AraxisMerge绿色版”是免安装版本,无需复杂的安装过程,用户可以...

    开源软件 winmerge 代码

    - **逐行比较**:WinMerge 可以对两份文本文件进行逐行比较,高亮显示不同之处,使用户一目了然地看到哪些行发生了变化。 - **二进制比较**:除了文本文件,WinMerge 还支持二进制文件的比较,如图片、音频或视频...

    Mybatis批量foreach merge into的用法

    Mybatis批量foreach merge into的用法是通过Mybatis的动态SQL语法foreach循环插入实现的,这种方法可以批量插入时间价格表数据。如果某个套餐的某天的价格存在,则更新,不存在则插入。下面是该方法的详细介绍: ...

    Hibernate save persist merge探究

    四、源码分析 深入源码可以帮助我们更清晰地理解这三个方法的工作原理。在Hibernate Core中,save()和persist()的实现基本相似,都通过调用IdentityGenerator生成ID,然后添加到持久化上下文。而merge()则涉及到了...

    WinMerge(文件比较)

    WinMerge是一款高效且易于使用的文件比较软件,尤其在IT领域中,它被广泛用于代码版本控制、文档差异分析等场景。该软件能够帮助用户快速识别并解决文件之间的差异,从而提高工作效率。下面我们将深入探讨WinMerge的...

    P4Merge, Linux上最好用的merge工具,附git集成

    P4Merge是一款强大的可视化三向合并工具,尤其在Linux环境中,它被广泛认为是最佳的merge工具之一。由Perforce公司开发,P4Merge以其清晰的界面、强大的冲突解决能力和高效的工作流程而受到开发者们的喜爱。本文将...

    Winmerge插件(16进制比较查看插件)(含源码)

    Winmerge 16进制比较查看插件 识别格式: .exe .dll .bin .ocx 编译环境:VC++ 6.00, XP系统。 在WinMerge 2.12.0.0 版本上稳定使用。 安装: 将dll文件复制到"x:\WinMerge安装目录\WinMerge\MergePlugins内,...

    WinMerge.zip

    WinMerge是一款强大的文本比较工具,尤其在IT行业中,它被广泛用于代码的差异对比和版本控制。这款软件能够帮助开发者迅速地找出两个文件或者目录之间的差异,并提供方便的合并功能,极大地提升了工作效率。 标题...

    merge01 merge 比较工具1

    merge 比较工具 merge 比较工具merge 比较工具

    Merge工具 win Merge

    **Win Merge:一款强大的文件与文件夹比较工具** 在IT领域,经常需要处理不同版本的文件或代码,这时,一个高效的文件比较工具就显得尤为重要。Win Merge是一款深受开发者和普通用户喜爱的免费文件和文件夹比较工具...

Global site tag (gtag.js) - Google Analytics