Con*_*D55 5 optimization session hibernate insert save
我想知道如何通过我的 Hibernate (4) & Oracle 设置减少 SQL 更新。
一个简单的案例可能是这样的:
打开一个会话/事务,使用 session.save() 创建一个新实体 Xyz,处理一些业务逻辑,对 Xyz 进行一些更改并调用 session.update(),然后让会话正常关闭,并通过提交到数据库休眠。
提交时,Hibernate 将执行插入操作,然后执行更新 —— 但它真正需要做的只是一次插入操作,但在本例中使用 Xyz的最新属性。
有没有人有做这种事情的任何想法/模式?或者有什么方法可以改变 Hibernate 的行为?或者你对此有什么看法——它是一个完整的反模式吗?
我知道 Hibernate 足够聪明,可以省略多个更新,当一个更新只是覆盖另一个更新时——那么为什么插入不相似呢?
这个小片段可以重现“问题”:
MyEntity e = new MyEntity("xxx");
Session session = sessionFactory.openSession();
session.beginTransaction();
session.save(e); e.setName("yyy");
session.getTransaction().commit();
session.close();
Run Code Online (Sandbox Code Playgroud)
顺便说一下,我没有什么可担心的触发因素。
这个例子非常简单,性能问题可能看起来微不足道,但实际上我正在处理一个更复杂的对象(即多次插入和更新),而且数量很大,所以避免更新会很好。
小智 1
有没有一种方法可以将对象添加到会话中,并将其标记为持久性,但直到最后才调用 save() (即不会生成 INSERT)?
如果您想推迟执行Session.persist(Object)
直到会话刷新和/或事务关闭,请考虑使用重构。Session.save(Object)
INSERT
来自JBoss Hibernate 社区文档的第 10.2 节:
您还可以使用 persist() 代替 save(),其语义在 EJB3 早期草案中定义。
persist()
使瞬态实例持久化。但是,它不保证标识符值会立即分配给持久化实例,分配可能会在刷新时发生。 还保证如果在事务边界之外调用该语句,persist()
则不会执行该语句。INSERT
这对于具有扩展会话/持久性上下文的长时间运行的对话非常有用。save()
确实保证返回一个标识符。如果INSERT
必须执行 an 来获取标识符(例如“身份”生成器,而不是“序列”),则INSERT
无论您是在交易内部还是外部,都会立即发生。这在具有扩展会话/持久性上下文的长时间运行对话中是有问题的。
另一个有用的参考可以在本博客文章“将其全部放在一起”部分顶部的方法到场景网格的左上角单元格中找到,该单元描述了从未持久化的对象的行为,如下所示:persist()
- 对象作为新实体添加到持久性上下文
- 新实体插入到数据库中
flush()
/commit()
归档时间: |
|
查看次数: |
3269 次 |
最近记录: |