为什么休眠在SAVE之前执行SELECT?

时间:2011-04-08 05:37:32

标签: hibernate optimization

为什么hibernate在保存对象之前会做一个选择?

我在互联网上找不到有用的信息。这是每次保存之前的正常行为吗?我找到了这个话题,select Query Run for hibernateTemplate.save() - 保存,但我没有找到这个答案“权威”。我的意思是,如果我想在保存每个对象之前避免这种选择,我们是否必须使用版本控制?

我很感激所有的解释或链接。

3 个答案:

答案 0 :(得分:3)

所以Julia是对的,使用已分配ID的实体调用Session.save()会导致hibernate执行SELECT,然后执行INSERT。幸运的是有两种解决方法:

  • 不要预先指定您的ID(不适合我)
  • 致电Session.persist()而非Session.save()

第二个选项也可以与Envers无缝协作。

希望这可以节省其他人狩猎的时间。

答案 1 :(得分:1)

不,它在保存之前不进行选择。你确定你的编辑保存用例是对的吗? Web应用程序的常见流程是:

  • 用户点击(GET)/ products / 5 / edit
  • 服务器将产品#5提取到http会话
  • 服务器返回html表单以编辑Product#5
  • 用户提交(POST)表单
  • 服务器从http会话中获取产品#5
  • 服务器从请求中填充
  • 服务器将填充的Product#5合并回hibernate

将执行单个sql更新,该更新也处理版本控制。如果版本号不同步,则会抛出StaleObjectStateException

答案 2 :(得分:1)

我知道你在问题的评论中已经回答了你自己的问题,但这里只是总结一下。

为了澄清,NHibernate在“SQL INSERT”中使用“save”,在“SQL UPDATE”中使用“update”。

我知道NHibernate在持久化之前会从db中隐式获取一个对象(没有明确使用s.Update)这些常见的场景:

  1. 在session_flush / transaction_commit(取决于设置)的映射中,select-before-update设置为“true”;
  2. 使用SaveOrUpdate时,实例的标识符的值表明它存在于db中;
  3. 在s.Delete之前。
  4. 与您的示例一样,当使用父子对象时(但简单的规则保持不变),这可能并不明显,因为从提取子项的代码中可能并不明显。