【问题标题】:Hibernate persist vs save休眠持续与保存
【发布时间】:2013-11-28 10:25:08
【问题描述】:

当我试图理解 Hibernate Save 和 persist 之间时,我遇到了这个解释:

persist() 定义明确。它使瞬态实例持久化。 但是,它不保证标识符值将是 立即分配给持久实例,分配可能 发生在冲洗时间。规范没有这么说,这是问题所在 我有坚持()。

persist() 还保证它不会执行 INSERT 语句 如果在事务边界之外调用它。这在 具有扩展会话/持久性的长期对话 语境。

需要像 persist() 这样的方法。

save() 不保证相同,它返回一个标识符,如果 必须执行 INSERT 以获取标识符(例如“身份” 生成器,而不是“序列”),这个 INSERT 立即发生,不管 如果您在交易之内或之外。这不好 具有扩展会话/持久性的长期对话 上下文。

能否请您帮助我理解persist 的行:

persist() 还保证它不会执行 INSERT 语句 如果在事务边界之外调用它。这在 具有扩展会话/持久性的长期对话 上下文。

这里的事务边界是什么?什么是长期对话?扩展会话/持久性上下文是什么意思?

还有保存方法:

这个 INSERT 会立即发生,无论你是在里面还是 交易之外。这在长期运行中并不好 与扩展会话/持久性上下文的对话。

我知道如果我们在我的程序中使用 save 方法来保存对象,我们不需要像 session.beginTransaction() 和 session.getTransaction().commt() 这样的语句。如果声明在这里说同样的话,请告诉我。那么这在长时间的对话中有何用处?

我是hibernate的新手,很难理解这些差异,请你帮我理解这些差异。

【问题讨论】:

标签: java hibernate


【解决方案1】:

顾名思义,hibernate save() 可用于将实体保存到数据库。我们可以在事务之外调用这个方法。如果我们在没有事务的情况下使用它并且我们在实体之间有级联,那么除非我们刷新会话,否则只有主实体会被保存

Hibernate 持久化类似于保存(使用事务),它将实体对象添加到持久化上下文中,因此可以跟踪任何进一步的更改。如果在提交事务或刷新会话之前更改了对象属性,它也会被保存到数据库中。 此外,我们只能在事务的边界内使用 persist() 方法,因此它是安全的并且可以处理任何级联对象。 最后,persist 不会返回任何内容,因此我们需要使用持久化对象来获取生成的标识符值。

【讨论】:

    【解决方案2】:

    save 和 persist 方法的主要区别之一在于 ID 生成策略。基本上 save() 方法会将 value(id) 返回给客户端,而 persist() 方法不会..

    1) 在您让 ORM 引擎为您生成 ID 的情况下,您可以使用 save()。原因很简单“Hibernate 让您有机会了解它生成/使用的 ID持久化你的对象“

    2)如果您自己生成了您的 id(分配的 ID 生成策略)并将其传递给 ORM 引擎以使用它来持久化您的对象。在这种情况下,persist() 将是合适的。

    点击here

    正如我所说的

    “这取决于 ID 生成策略”

    干杯!

    【讨论】:

      【解决方案3】:

      您的问题与 Hibernate 实现的 Open Session in View 模式有关。

      这个想法是,您可能在 Web 应用程序中有一个原子工作单元,需要在整个特定进程中运行。想象一下在线订购食物。您在一个页面上登录,在下一页选择披萨和配料,在下一页添加甜点,在下一页添加饮料,然后在最后一页付款。您希望整个过程成为一个单一的工作单元。

      因此,Hibernate Session 需要在该工作单元开始时打开并在结束时关闭——手动或通过某种容器管理。

      在该对话期间调用persist 不会导致任何数据插入,但它会使分离的实体持久化。 Hibernate 将“记录”所有要进行的插入,然后在对话结束时刷新它们。

      同时save 立即执行插入并为您的实体提供数据库中的 id。这在长时间运行的对话中并不好,因为您希望您的数据库操作是原子的——全有或全无。可能会发生奇怪的事情,例如多次插入相同的数据。

      希望对您有所帮助。

      【讨论】:

      • 那么你会将不同请求之间的 Hibernate Session 存储在哪里?你会把它放在HttpSession中吗?
      • 您的第二段描述了类似于接缝对话的内容,它与 open-session-in-view 完全分开。在用户思考期间,交易几乎不应该保持打开状态。我认为你需要一个更好的例子。
      • 确实,我的示例可以描述 Seam 对话,至少早在 2012 年 Seam 还是一个东西的时候。您似乎混淆了不同的抽象级别——Hibernate 的持久性问题和 Seam 的中间件问题。两者并不相互排斥,因此该示例可以同时描述这两件事。尽管如此,我毫不怀疑还有更好的例子。但我认为,对于 OP 和其他人来说,提供一个更好的例子比仅仅提供它存在的可能性会更具建设性和趣味性。
      【解决方案4】:

      save() 方法可以返回由 hibernate 生成的主键 id 值,我们可以通过

      long s = session.save(k);
      

      在同样的情况下,persist() 永远不会将任何价值回馈给客户,希望您清楚。

      所以persist() 方法保证如果在事务边界之外调用它不会执行 INSERT 语句,因为在持久化对象后不需要获取 id。

      save() 方法并不能保证相同,因为它需要返回一个标识符(可能是主键id)。

      必须执行 INSERT 以获取标识符(例如“身份”生成器),因此,无论您是在事务内部还是事务外部,此 INSERT 都会立即与 save() 发生。

      【讨论】:

      • 但是如果我不提交/刷新事务怎么办?执行了哪个保存方法的插入有什么用?
      猜你喜欢
      • 2011-12-16
      • 1970-01-01
      • 2011-01-25
      • 1970-01-01
      • 1970-01-01
      • 2012-09-09
      • 2021-09-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多