当我试图理解Hibernate Save和persist之间时,我遇到了这个解释:
persist()定义明确。它使瞬态实例持久化。 但是,它不保证标识符值 如果立即分配给持久化实例,则分配可能 在冲洗时发生。规范没有说明,这是问题所在 我有坚持()。
persist()还保证它不会执行INSERT语句 如果在事务边界之外调用它。这很有用 长时间运行的会话与扩展的会话/持久性 上下文。
需要像persist()这样的方法。
save()不保证相同,它返回一个标识符,如果 必须执行INSERT才能获得标识符(例如“身份”) 生成器,而不是“序列”),这个INSERT立即发生,无论如何 如果您在交易内部或外部。这不是一件好事 与长时间会话/持久性的长时间对话 上下文。
请你帮助我理解坚持的说法:
persist()还保证它不会执行INSERT语句 如果在事务边界之外调用它。这很有用 长时间运行的会话与扩展的会话/持久性 上下文。
这里有什么交易边界?什么是长期对话?什么是扩展的会话/持久化上下文意味着什么?
另外还有保存方法:
无论你是在里面还是在内,这种INSERT都会立即发生 在交易之外。这在长期运行中并不好 与扩展的会话/持久化上下文对话。
我知道如果我们在程序中使用save方法来保存对象,我们就不需要像session.beginTransaction()和session.getTransaction()。commt()这样的语句。如果声明在这里说同样的话,请告诉我。那么这对于长时间运行的对话有什么用呢?
我是新手,并且发现很难理解这些差异,请你帮我理解差异。
答案 0 :(得分:4)
您的问题与Hibernate实现的Open Session in View模式有关。
这个想法是,您可能在Web应用程序中有一个原子工作单元,需要在整个特定进程中运行。想象一下在线订购食物。您在一个页面上登录,在下一页上选择披萨和浇头,在下一页上添加甜点,在下一页上添加饮料,然后在最后一页上付款。您希望整个过程成为一个单一的工作单元。
因此,Hibernate Session
需要在该工作单元的开头打开并在结束时关闭 - 手动或通过某种容器管理。
在该对话期间调用persist
不会导致任何数据插入,但会使分离的实体持久化。 Hibernate会“记录”所有插入内容,然后在会话结束时刷新它们。
同时save
立即执行插入操作,并为您的实体提供数据库中的id。这在长时间运行的会话中并不好,因为您希望数据库操作是原子的 - 全部或全部。可能会发生类似数据的多次插入等奇怪的事情。
希望有所帮助。
答案 1 :(得分:1)
save()
方法可以返回由hibernate生成的主键id值,我们可以通过
long s = session.save(k);
在同样的情况下,persist()
永远不会给客户任何价值,希望你清楚。
所以persist()
方法保证如果在事务边界之外调用它,它就不会执行INSERT语句,因为在持久化对象之后不需要获取id。
尽管save()
方法不保证相同,因为它需要返回一个标识符(可能是主键id)。
必须执行INSERT以获取标识符(例如“identity”生成器),因此,无论您是在事务内部还是外部,此INSERT都会立即与save()
一起发生。
答案 2 :(得分:1)
保存和持久方法之间的关键区别之一取决于ID生成策略。基本上save()方法会将值(id)返回给客户端并且persist()方法不会..
1)如果您让ORM引擎为您生成ID,在这种情况下您可以使用save()。原因很简单“Hibernate让您有机会了解它生成/使用的ID坚持你的对象“
2)如果您已经自己生成了id(分配了ID生成策略)并将其传递给ORM引擎以使用它来持久化您的对象。在这种情况下,persist()将是合适的。
点击here
正如我所说
“这取决于ID生成策略”
干杯!
答案 3 :(得分:0)
正如方法名称所示,hibernate save()可用于将实体保存到数据库。我们可以在事务外调用此方法。如果我们在没有事务的情况下使用它,并且我们在实体之间进行级联,那么除非我们刷新会话,否则只保存主实体
Hibernate persist类似于save(with transaction),它将实体对象添加到持久化上下文中,因此跟踪任何进一步的更改。如果在提交事务或刷新会话之前更改了对象属性,则它也将保存到数据库中。 此外,我们只能在事务的边界内使用persist()方法,因此它是安全的并且可以处理任何级联对象。 最后,persist不返回任何内容,因此我们需要使用持久化对象来获取生成的标识符值。