1

以下代码在调用“em.refresh(p)”时抛出异常:

1: EntityManager em = emf.createEntityManager();
2: em.getTransaction().begin();
3:
4: Product p = new Product("J&D", 35.0,"Whisky");
5: em.persist(p);
6:
7: em.refresh(p);
8: em.getTransaction().commit();
9: em.close();

在调试代码时,我们看到 Hibernate 没有在第 6 行将记录写入数据库。他确实做到了 - 在需要时,而不是更早。

在第 7 行,我们得到以下异常: 线程“main”中的异常 javax.persistence.PersistenceException: org.hibernate.HibernateException: 这个实例在数据库中还没有作为一行存在

当我们在第 6 行强制 Hibernate 将记录刷新到 DB 中时,执行 INSERT 并且不会发生错误。我们可以通过执行选择或强制刷新来做到这一点(有所有后果):

6 : em.createQuery("select p from Product p").getResultList();
6 : em.flush();

我的问题:“刷新”方法是否应该不强制 Hibernate 将记录写入数据库,就像之前放置的 select 或 flush 语句一样?(这可能是一个错误吗?)。

提前感谢您的回答。

皮埃尔

4

1 回答 1

5

方法“刷新”是否应该不强制 Hibernate 将记录写入数据库,就像之前放置的 select 或 flush 语句一样?(这可能是一个错误吗?)。

不,refresh不应该刷新更改,因为整个点refresh还原在当前事务中所做的任何未刷新的更改。这在 JPA wiki book 中可能比在规范中更好地解释:

EntityManager#refresh(Object) 操作用于从数据库中刷新对象的状态。这将恢复在当前事务中对对象所做的任何未刷新的更改,并将其状态刷新为数据库上当前定义的状态。如果flush发生了 a ,它将刷新到已刷新的内容。必须在托管对象上调用刷新,因此如果您有非托管实例,您可能首先需要find使用活动的对象。EntityManager

所以如果你想让你的代码工作,你确实应该flush在之后。persist

话虽如此,我没有看到在 arefresh之后执行 a 的意义persist(假设您刷新了更改),这里没有什么可以刷新的。也许这只是一个简化的例子。

参考

  • JPA 2.0 规范
    • 3.2.5 刷新实体实例
  • JPA 维基书
于 2010-10-23T14:17:00.567 回答