2012-02-08 44 views
6
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,它注释掉了,因为我是干运行此代码第一。然而,事实证明它并不是非常干燥。在检查数据库时,我发现数据发生了变化(幸运的是它是一个测试数据库)。是否JPA/Hibernate的保存,即使不调用persist

显然我对Hibernate/JPA的理解是有缺陷的。不要求拨打persist始终需要更改数据?如果没有,什么时候保存的规则是什么?

+0

但你在调用commit? – 2012-02-08 16:20:45

回答

9

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

+0

很高兴知道。这可以依赖,还是一个“坚持”的呼吁仍然明智? – 2012-02-08 16:25:41

+0

@Bart只有**托管的**实体以这种方式保存,托管意味着用于加载这些实体的实体管理器尚未关闭,所以要小心。坚持不懈地创造一个新的实体。如果你在一个已经存在的实体(如这里)中使用它,它会抛出一个异常。看看API:[链接](http://docs.oracle.com/javaee/6/api/javax/persistence/EntityManager.html) – Pablo 2012-02-08 16:32:11

+0

但是我一直使用'persist'加载实体,没有例外。 – 2012-02-08 16:43:46

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

这行代码检索来自EM届StringData是例如SD,您所作的任何更改都将(交易结束时)保存在冲洗,因为对象实例与EM会话相关联(即管理)。

你可以分离它,或从方法中返回它。在事务之外,它不会与em会话相关联,只有在通过合并重新连接之后,更改才会被保留。

+0

重要的部分不是事务被提交,重要的部分是实体管理器被关闭。如果事务已提交但实体管理器未关闭,则实体仍与实体管理器关联。 – Pablo 2012-02-08 16:38:38

+0

@Pablo那么如果实体在事务外部被更改,但在实体管理器内部发生了什么呢? – 2012-02-08 17:28:00

+0

@Bart实体管理器将在下次调用flush()或commit()时尝试保存它。 – Pablo 2012-02-08 17:50:49

相关问题