2014-04-22 74 views
1

使用更新查詢下面的代碼:與objectdb

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

UPDATE查詢繞過EntityManager,這意味着EntityManager可能沒有數據庫中真實對象的最新視圖。

正如UPDATE queries page的ObjectDB手冊中解釋說:

「使用更新查詢可能會略高於檢索實體對象,然後將其更新更高效的更新數據庫中的實體對象,但應謹慎,因爲使用繞過EntityManager可能會破壞與數據庫的同步,例如,EntityManager可能不知道持久化上下文中的緩存實體對象已被UPDATE查詢修改過,因此,最好使用單獨的EntityManager for更新查詢。「

使用一個單獨的EntityManager正是你在修改過的代碼中關閉和打開一個新的EntityManager所做的。

或者,如果你想使用同一個EntityManager,你可以在clear its persistence context(即它的緩存)之後運行UPDATE查詢,然後再運行SELECT查詢。