Session.SaveOrUpdate Copy() 和 Session.Merge() 有什么区别?

2024-01-01

在 NHibernate 3.1 中,ISession.SaveOrUpdateCopy()已被标记为已弃用。该文档建议使用Merge()反而。每个的文档如下:

SaveOrUpdateCopy(object obj)

将给定对象的状态复制到具有相同标识符的持久对象上。如果当前没有关联的持久实例 会话,它将被加载。返回持久化实例。如果 给定实例未保存或数据库中不存在,保存它并 将其作为新的持久实例返回。否则,给定的实例 不会与会话关联。

Merge(object obj)

使用相同的方法将给定对象的状态复制到持久对象上 标识符。如果当前没有关联的持久实例 会话,它将被加载。返回持久化实例。如果 给定实例未保存,保存副本并将其作为新持久的返回 实例。给定实例不会与会话关联。 如果关联已映射,则此操作会级联到关联实例 和cascade="merge".
该方法的语义由 JSR-220 定义。

它们在我看来几乎一模一样,但肯定存在一些微妙之处。如果有,它们是什么?


保存或更新副本现在被认为已过时,因此Merge旨在接管它(因此它极其相似)。

它们几乎是相同的,只是我不认为这些级联选项可用保存或更新副本。然而,这一点没有实际意义,因为Merge应该是你使用的方法。


UPDATE:我查看了 NHibernate 的源代码只是为了确保它们与我想象的一样相似,这就是我发现的。

Both Merge and 保存或更新副本有非常相似的实现:

public object Merge(string entityName, object obj)
{
    using (new SessionIdLoggingContext(SessionId))
    {
        return FireMerge(new MergeEvent(entityName, obj, this));
    }
}

public object SaveOrUpdateCopy(object obj)
{
    using (new SessionIdLoggingContext(SessionId))
    {
        return FireSaveOrUpdateCopy(new MergeEvent(null, obj, this));
    }
}

Their FireXXXX方法也很相似:

private object FireMerge(MergeEvent @event)
{
    using (new SessionIdLoggingContext(SessionId))
    {
        CheckAndUpdateSessionStatus();
        IMergeEventListener[] mergeEventListener = listeners.MergeEventListeners;
        for (int i = 0; i < mergeEventListener.Length; i++)
        {
            mergeEventListener[i].OnMerge(@event);
        }
        return @event.Result;
    }
}

private object FireSaveOrUpdateCopy(MergeEvent @event)
{
    using (new SessionIdLoggingContext(SessionId))
    {
        CheckAndUpdateSessionStatus();
        IMergeEventListener[] saveOrUpdateCopyEventListener = listeners.SaveOrUpdateCopyEventListeners;
        for (int i = 0; i < saveOrUpdateCopyEventListener.Length; i++)
        {
            saveOrUpdateCopyEventListener[i].OnMerge(@event);
        }
        return @event.Result;
    }
}

这些方法完全相同,只是它们利用不同的事件侦听器列表,但甚至列表的类型(IMergeEventListener) 是相同的!

查看侦听器列表,它们都是使用默认侦听器初始化的。默认侦听器Merge监听处理程序的类型默认合并事件监听器保存或更新副本 is 默认保存或更新复制事件监听器。因此,它们之间的区别只是这两种实现的区别(也就是说,如果您保留默认侦听器,这是 99% 的时间)。

然而,真正有趣的事实IS实施上的差异。如果你看默认保存或更新复制事件监听器你得到这个:

public class DefaultSaveOrUpdateCopyEventListener : DefaultMergeEventListener
{
    protected override CascadingAction CascadeAction
    {
        get { return CascadingAction.SaveUpdateCopy; }
    }
}

这意味着默认行为Merge and 保存或更新副本只是级联动作有所不同,其他一切都完全相同。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Session.SaveOrUpdate Copy() 和 Session.Merge() 有什么区别? 的相关文章

随机推荐

  • 在 Android 中格式化 EditText 的电话号码

    我正在制作一个简单的地址簿应用程序 针对 4 2 它需要姓名 地址 城市 州 邮政编码和电话 我想将输入的电话号码格式化为电话号码 XXX XXX XXXX 但我需要将值作为字符串取出 以便在保存时可以将其存储在数据库中 我怎样才能做到这一
  • 从 Internet Explorer 检索所有 cookie

    我正在尝试检索与我打开的特定页面 我已经通过身份验证 关联的所有 cookie 有多个与该网页关联的 cookie 我需要检索每个 cookie 以便稍后进行 POST 我尝试了几种方法 但没有一个给我完整的列表 到目前为止 我已经用 VB
  • 如何在 VS Code 中调试 scala sbt 项目

    我正在尝试在 vs code 中调试 sbt 项目 我已经下载了 VS Code 扩展名 scala Metals 如何在 scala Metal 中显式添加 build sbt 文件夹路径 如何在 scala Metal 中显式添加 bu
  • D3 非连续日期域在 X 轴上产生间隙

    我想绘制一些不连续的时间序列数据 周末 假期等日期的间隙 这是每日数据 数据看起来像这样 date value 1 2 15 109 33 1 5 15 106 25 1 6 15 106 26 1 7 15 107 75 1 8 15 1
  • 忽略Excel求和公式中的隐藏列

    我基本上想忽略Excel中的随机列 有没有办法检测某列是否隐藏 然后不在公式中包含该列 例子是 F1 B1 C1 E1 忽略D列 但第二天 F 栏可能需要 B D E 来代替 有没有办法简单地实现这一目标 我见过一些忽略特定列的公式 但没有
  • 如何检查 Magento 产品是否已添加到购物车?

    我想在 Magento 中首次将产品添加到购物车时显示弹出窗口 并且不想在再次添加或更新产品时显示弹出窗口 简而言之 我想知道将要添加到购物车中的产品是第一次出现还是不是第一次出现 答案很大程度上取决于您想要如何处理父 子类型产品 如果需要
  • 同一应用程序中可以加载不同版本的 DLL 吗?

    我的应用程序使用一个版本的库 a dll 我使用另一个 DLL b dll 它又使用我使用的同一库 a dll 的旧版本 我正在通过嵌入清单文件来构建应用程序 我使用的 DLL 也使用嵌入式清单文件 我的 WinSXS 文件夹中有两个版本的
  • 无法访问 Heroku 上的作曲家供应商文件夹

    我在 Heroku 上托管一个 PHP 应用程序 它使用 Composer 安装 Bootstrap 当我将应用程序部署到 Heroku 时 所有 Composer 依赖项都按预期安装在 vendor 子目录中 我现在尝试将 Bootstr
  • 是否有任何有效的用例可以在现代 C++ 中使用 new 和 delete、原始指针或 c 样式数组?

    这里有一个值得注意的video 停止教学C https www youtube com watch v YnWhqhNdYyk关于 C 语言教学中范式的改变 还有一篇值得注意的博客文章 我有一个梦想 http dev jungle blog
  • 如何打开 Outlook 新邮件窗口 C#

    我正在寻找一种方法在 Outlook 窗口中打开新邮件 我需要以编程方式填充 从 到 主题 正文信息 但保持此新邮件窗口打开 以便用户可以验证内容 添加内容 然后作为正常的 Outlook 消息发送 发现 Process Start Str
  • 排序后 QTableWidget 的填充不完整

    我有一个 QTableWidget 它将填充一些随机值 该表已启用排序 tableWidget setSortingEnabled True 排序工作正常 我知道 在这个最小的例子中 它将是按字母数字排序的数字 但是 当我按一列对表格进行排
  • 致命错误:未捕获反射异常:类配置不存在

    我正在 Laravel 5 8 上开发一个电子商务项目 但由于我不小心在项目文件夹上运行了 laravel new 命令 当我尝试在本地服务器上启动该项目时 我收到此错误 致命错误 未捕获的 ReflectionException C wa
  • GROUP BY 中选择了哪一行?

    假设我有一张桌子 lang title url pt Livro 1 o294jl en Book 1 o294jl en Book 2 o294jl 我运行一个查询 SELECT lang title FROM table GROUP B
  • java.lang.ClassCastException:在 java 1.6 中,java.lang.Long 无法转换为 java.lang.Integer

    就连我也在选角Object到 int 中 但是出现这个异常 实际上我的 Hibernate JPA 方法是 returnObject然后我将其转换为Object into int 这是我的休眠代码 Transactional public
  • 如何在 Vim 中折叠 C++ 风格的注释?

    Vim 中的语法折叠可以轻松地为区域创建折叠 可以使用正则表达式定义折叠的开始和结束 syn 区域 myRegion start region end endregion 透明 keepend 扩展折叠 但是 我不确定如何使用语法折叠来定义
  • 捕获一个字符串,然后匹配以该字符串开头的所有其他单词

    我有一个包含 80 000 多个单词的列表 每个单词都用换行符分隔 我需要匹配每个包含较小单词作为前缀的单词 例如 bald lt captures bald balder lt matches because it starts with
  • 如何在 Docker 容器上安装 Access Runtime?

    我想在 Docker 容器上安装 Access Runtime 但这样做时遇到了失败 以下是重现错误的基本命令 首先使用新的 Windows 容器启动交互式 shell docker container run it mcr microso
  • C# 更新 DLL,无需重新编译项目

    我编写了一个小程序 其中引用了将包含在安装文件中的 dll 文件 我还需要一种更新dll的方法 以防我更改某些功能 而不需要再次重新下载整个程序 只需替换dll文件 这可能吗 我刚刚在某处读到我必须使用新的 dll 版本更新 xml 文件
  • 当一个变量=另外两个而不是一个时如何使用替换

    好吧 这个可能有点难 我使用的 VB 看起来像这样 string Replace string ToLower chr 63 A 但我也想要 chr 63 B 如下所示 string Replace string ToLower chr 6
  • Session.SaveOrUpdate Copy() 和 Session.Merge() 有什么区别?

    在 NHibernate 3 1 中 ISession SaveOrUpdateCopy 已被标记为已弃用 该文档建议使用Merge 反而 每个的文档如下 SaveOrUpdateCopy object obj 将给定对象的状态复制到具有相