Использование запросов обновления с помощью 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();
</point></point>

выдает: 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();
</point></point>

Результат такой же, как и ожидалось:

Координация X: 1001

Что я сделал неправильно в первом фрагменте кода?

1 ответ

Запросы UPDATE обходят EntityManager, что означает, что EntityManager может не иметь обновленного представления реальных объектов в базе данных.

Как поясняется на странице запросов UPDATE в руководстве ObjectDB:

"Обновление объектов объекта в базе данных с помощью запроса UPDATE может быть несколько более эффективным, чем извлечение объектов объекта, а затем их обновление, но его следует использовать осторожно, поскольку обход EntityManager может нарушить его синхронизацию с базой данных. Например, EntityManager может не работать помните, что объект кэшированного объекта в контексте его персистентности был изменен с помощью запроса UPDATE. Поэтому хорошей практикой является использование отдельного EntityManager для запросов UPDATE ".

Использование отдельного EntityManager - это именно то, что вы сделали, закрыв и открыв новый EntityManager в вашем обновленном коде.

В качестве альтернативы, если вы хотите использовать тот же EntityManager, вы можете очистить свой контекст персистентности (т.е. его кеш), после выполнения запроса UPDATE и перед запуском запроса SELECT.

licensed under cc by-sa 3.0 with attribution.