提问者:小点点

持久性上下文缓存 id 和 SQL 查询?


如果一次调用<code>会话。保存(customerObject)则不需要插入客户…查询数据库。Hibernate将设置id属性(“序列”或“增量”生成器),并将实体绑定到持久性上下文。当<code>事务时,持久性上下文与数据库同步。调用commit()
Q:Hibernate将在哪里设置id属性
Q:在与db同步之前,持久性上下文缓存sql查询是否会插入到customer…中?我的意思是,何时生成sql(在执行save或session.flush/tx.commit时)

编辑:下面是我从https://forum.hibernate.org/viewtopic.php?t=951275

persist()定义得很好。它使瞬态实例持久化。但是,它不能保证标识符值会立即分配给持久性实例,分配可能发生在刷新时。规范没有这么说,这就是我对persist()的问题。

persist()还保证,如果在事务边界之外调用INSERT语句,它将不会执行该语句。这在具有扩展会话/持久性上下文的长时间运行会话中非常有用。

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

save() 不保证相同,它返回一个标识符,如果必须执行 INSERT 来获取标识符(例如,“身份”生成器,而不是“序列”),则此 INSERT 会立即发生,无论您在事务内部还是外部。这在具有扩展会话/持久性上下文的长期运行对话中是不好的。

这更令人困惑


共1个答案

匿名用户

一般来说,Hibernate会在不损害程序正确性的情况下,通过尊重它所提供的方法的契约,尽可能晚地写入数据库。

由于save()被记录为向保存的实体分配一个ID并返回该ID,因此它在调用save()时生成ID并返回它。这可能意味着实体是否写入数据库,具体取决于ID生成策略。

由于持久化()不保证在调用标识符时分配标识符,因此您不能指望在调用持久化()后分配ID。您也不能期望实体被写入数据库,因为这不是持久化()所做的。就这么简单。

只有在刷新会话时、在提交之前自动执行或在调用 flush() 时显式执行对 DB 的写入才保证执行。您还可以保证,如果执行查询的结果可能取决于挂起的写入,则执行对 DB 的写入。