Hibernate v3.6:EntityManager方法问题"刷新"

1 orm hibernate jpa entitymanager jpa-2.0

以下代码在调用"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();
Run Code Online (Sandbox Code Playgroud)

在调试代码时,我们看到Hibernate没有在第6行将记录写入数据库.他的确如预见 - 当需要时,而不是更早.

在第7行,我们得到以下异常:线程"main"中的异常javax.persistence.PersistenceException:org.hibernate.HibernateException:此实例尚未作为数据库中的行存在

当我们强制Hibernate在第6行将记录刷新到DB时,执行INSERT并且不会发生错误.我们可以通过执行select或只强制刷新来执行此操作(具有所有后果):

6 : em.createQuery("select p from Product p").getResultList();
6 : em.flush();
Run Code Online (Sandbox Code Playgroud)

我的问题:如果方法"刷新"不强制Hibernate将记录写入数据库,那么我们之前放置的select或flush语句也是如此?(这可能是个错误吗?).

提前感谢您的回答.

皮埃尔

Pas*_*ent 5

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

不,refresh不应该刷新更改,因为整个目的refresh还原当前事务中所做的任何非刷新更改.这可能在JPA维基书中比在规范中更好地解释:

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

所以你应该确实flushpersist你想要你的代码工作之后.

话虽这么说,我没有看到在a refresh之后做一个persist(假设你刷新了变化),这里没有什么可以刷新的.也许它只是一个简化的例子.

参考

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