【问题标题】:Hibernate v3.6 : Issue with the EntityManager method "refresh"Hibernate v3.6:EntityManager 方法“刷新”的问题
【发布时间】:2011-04-29 13:53:00
【问题描述】:

以下代码在调用“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 行,我们得到以下异常: 线程“主”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 语句一样? (这可能是一个错误吗?)。

提前感谢您的回答。

皮埃尔

【问题讨论】:

    标签: hibernate orm jpa jpa-2.0 entitymanager


    【解决方案1】:

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

    不,refresh 不应该刷新更改,因为refresh 的全部目的是还原当前事务中所做的任何未刷新的更改。这在 JPA wiki 书籍中可能比在规范中更好地解释:

    EntityManager#refresh(Object) 操作用于刷新 来自数据库的对象状态。这 将还原任何未刷新的更改 在当前交易中向 对象,并将其状态刷新到什么 当前在数据库中定义。 如果出现flush,它将 刷新到刷新的内容。刷新 必须在托管对象上调用,所以 您可能首先需要find 对象 如果您使用活跃的EntityManager 有一个非托管实例。

    因此,如果您希望您的代码正常工作,您确实应该在 persist 之后使用 flush

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

    参考文献

    • JPA 2.0 规范
      • 3.2.5 刷新实体实例
    • JPA 维基书

    【讨论】:

      猜你喜欢
      • 2011-01-05
      • 2011-08-15
      • 2021-11-17
      • 1970-01-01
      • 2015-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多