简体   繁体   English

即使不调用persist,JPA/Hibernate也会保存吗

[英]Does JPA/Hibernate save even when not calling persist

em.getTransaction().begin();

StringData sd = em.find(StringData.class, key);
System.out.println("Old value: " + sd.getData());
sd.setData(newValue);
// em.persist(sd);

em.getTransaction().commit();

As you can see, I'm not calling persist , it's commented out, because I'm dry running this code first.正如你所看到的,我没有调用persist ,它被注释掉了,因为我先干运行这段代码。 However, as it turns out it's not so very dry.然而,事实证明它并不是那么干燥。 Upon inspecting the database, I see the data is changed (fortunately it's a test database).检查数据库后,我看到数据已更改(幸运的是它是一个测试数据库)。

Apparently my understanding of Hibernate/JPA is flawed.显然我对 Hibernate/JPA 的理解是有缺陷的。 Isn't calling persist always required to change data?不是总是需要调用persist来更改数据吗? And if not, what are the rules on when something is saved?如果没有,什么时候保存东西的规则什么?

是的,如果在该实体上检测到任何更改,则在完成刷新(也通过提交完成刷新)时保存托管实体,这称为脏检查。

StringData sd = em.find(StringData.class, key);

That line of code retrieves the StringData instance sd from the em session, any changes you make will be saved on flush (when transactions ends) because the object instance is associated with the em session (ie managed).该行代码从 em 会话中检索 StringData 实例 sd,您所做的任何更改都将在刷新时保存(当事务结束时),因为对象实例与 em 会话相关联(即托管)。

You could detach it, or return it from the method.你可以分离它,或者从方法中返回它。 Outside of the transaction it is not associated with em session and changes will not be persisted until it is re-attached via merge.在事务之外,它不与 em 会话相关联,并且在通过合并重新附加之前,更改不会持久化。

The accepted answer is slightly misleading.接受的答案有点误导。 Managed entities are saved automatically on flush but flush is not issued "if any change is detected".托管实体在刷新时自动保存,但“如果检测到任何更改”则不会发出刷新。 This is misleading as it implies that flush happens on any change instantly.这是一种误导,因为它意味着刷新会立即发生在任何更改上。

Instead, with the default AUTO flush mode, a flush is triggered on very specific conditions.相反,使用默认的 AUTO 刷新模式,会在非常特定的条件下触发刷新。

Example 1 - If you interleave a native SQL within your transaction.
Example 2 - If you write a JPQL/HQL query that overlaps with cache.
Example 3 - If you exit the transaction normally.

My point is that it's not an immediate flush but rather triggered only when certain conditions are met.我的观点是它不是立即刷新,而是仅在满足某些条件时触发。 This is subtle but important distinction.这是微妙但重要的区别。

Reference - https://docs.jboss.org/hibernate/orm/5.1/userguide/html_single/chapters/flushing/Flushing.html参考 - https://docs.jboss.org/hibernate/orm/5.1/userguide/html_single/chapters/flushing/Flushing.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM