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();
正如你所看到的,我没有打电话给persist
,它被注释掉了,因为我先干这个代码。然而,事实证明它并不是那么干燥。在检查数据库时,我看到数据已更改(幸运的是它是一个测试数据库)。
显然我对Hibernate / JPA的理解是有缺陷的。是不是总是要求persist
来更改数据?如果没有, 的保存时间是什么规则?
答案 0 :(得分:10)
是的,如果检测到任何更改,则在完成刷新(刷新也通过提交完成)时保存托管实体,这称为脏检查。
答案 1 :(得分:3)
StringData sd = em.find(StringData.class, key);
该行代码从em会话中检索StringData实例sd,您所做的任何更改都将保存在flush(当事务结束时),因为对象实例与em会话(即托管)相关联。
您可以将其分离,或从方法中返回。在事务之外,它与em会话无关,并且在通过合并重新附加更改之前不会保留更改。
答案 2 :(得分:0)
接受的答案有点误导。托管实体在刷新时自动保存,但“如果检测到任何更改”则不会发出刷新。这是一种误导,因为它暗示刷新会立即发生在任何更改上。
相反,在默认的自动刷新模式下,会在非常特定的条件下触发刷新。
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.
我的观点是它不是立即刷新,而是仅在满足某些条件时才触发。这是微妙但重要的区别。
参考 - https://docs.jboss.org/hibernate/orm/5.1/userguide/html_single/chapters/flushing/Flushing.html