以下代码:
EntityManagerFactory emf = Persistence.createEntityManagerFactory("test.odb");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
Point p = new Point(0, 0);
em.persist(p);
em.getTransaction().commit();
em.getTransaction().begin();
Query query = em.createQuery("UPDATE Point SET x = 1001 where x = 0");
int updateCount = query.executeUpdate();
em.getTransaction().commit();
TypedQuery<Point> myquery = em.createQuery("SELECT p from Point p where p.x = 1001", Point.class);
List<Point> results = myquery.getResultList();
System.out.println("X coordinate is: " + results.get(0).getX());
em.close();
打印输出:X坐标为:0 这是错误的,因为X坐标应该是1001
但是,如果我将代码更改为:
EntityManagerFactory emf = Persistence.createEntityManagerFactory("test.odb");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
Point p = new Point(0, 0);
em.persist(p);
em.getTransaction().commit();
em.getTransaction().begin();
Query query = em.createQuery("UPDATE Point SET x = 1001 where x = 0");
int updateCount = query.executeUpdate();
em.getTransaction().commit();
em.close();
em = emf.createEntityManager();
TypedQuery<Point> myquery = em.createQuery("SELECT p from Point p where p.x = 1001", Point.class);
List<Point> results = myquery.getResultList();
System.out.println("X coordinate is: " + results.get(0).getX());
em.close();
结果与预期相同:
X coordiate是:1001
我在第一个代码段中做错了什么?
答案 0 :(得分:1)
UPDATE查询绕过EntityManager,这意味着EntityManager可能没有数据库中真实对象的最新视图。
如ObjectDB手册中的UPDATE queries page所述:
&#34;使用UPDATE查询更新数据库中的实体对象可能比检索实体对象然后更新它们更有效,但应谨慎使用它,因为绕过EntityManager可能会破坏与数据库的同步。例如,EntityManager可能不知道其持久化上下文中的缓存实体对象已被UPDATE查询修改。因此,最好使用单独的EntityManager进行UPDATE查询。&#34;
使用单独的EntityManager正是您在修订后的代码中关闭并打开新的EntityManager所做的。
或者,如果要使用相同的EntityManager,可以在运行UPDATE查询之后和运行SELECT查询之前clear its persistence context(即其缓存)。