当前位置: 首页 > 知识库问答 >
问题:

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

薛墨一
2023-03-14

如果一次调用<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个答案

颛孙子民
2023-03-14

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

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

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

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

 类似资料:
  • 问题内容: 我是Java世界和JPA的新手。我在学习JPA时遇到了许多新术语,例如Entity,persistence。在阅读时,我无法理解 Persistence Context 的确切定义。 谁能用简单的外行术语解释它?与中使用的数据有什么关系? 例如,我发现此定义太复杂而难以理解: 持久性上下文是一组实体,因此对于任何持久性标识,都有一个唯一的实体实例。 问题答案: 持久性上下文处理一组实体

  • 持久性上下文是一组实体,因此对于任何持久性标识都有一个唯一的实体实例。

  • 有一种方法可以绕过持久性上下文,只将实体用作数据库表的包装器?

  • 问题内容: 事务范围的持久性上下文和扩展的持久性上下文之间有什么区别? 问题答案: 在JSR-220 Enterprise JavaBeans 3.0规范中清楚地解释了差异: 5.6容器管理的持久性上下文 (…) 可以将容器管理的持久性上下文定义为具有范围为单个事务的生存期或跨越多个事务的扩展生存期,这取决于创建容器时所指定的生存期 。该规范分别将这种持久性上下文称为 事务范围的持久性上下文 和

  • 和RDD相似,DStreams也允许开发者持久化流数据到内存中。在DStream上使用persist()方法可以自动地持久化DStream中的RDD到内存中。如果DStream中的数据需要计算多次,这是非常有用的。像reduceByWindow和reduceByKeyAndWindow这种窗口操作、updateStateByKey这种基于状态的操作,持久化是默认的,不需要开发者调用persist(

  • 当使用修改查询时,我有一个问题,EntityManager在查询执行后包含过时的实体。 假设我们在DB中有电子邮件[ID=1,active=true,expire=2015/01/01]。 执行后: