如果一次调用<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 会立即发生,无论您在事务内部还是外部。这在具有扩展会话/持久性上下文的长期运行对话中是不好的。
这更令人困惑
一般来说,Hibernate会在不损害程序正确性的情况下,通过尊重它所提供的方法的契约,尽可能晚地写入数据库。
由于save()
被记录为向保存的实体分配一个ID并返回该ID,因此它在调用save()
时生成ID并返回它。这可能意味着实体是否写入数据库,具体取决于ID生成策略。
由于持久化()
不保证在调用标识符时分配标识符,因此您不能指望在调用持久化()
后分配ID。您也不能期望实体被写入数据库,因为这不是持久化()
所做的。就这么简单。
只有在刷新会话时、在提交之前自动执行或在调用 flush()
时显式执行对 DB 的写入才保证执行。您还可以保证,如果执行查询的结果可能取决于挂起的写入,则执行对 DB 的写入。