Использование запросов на обновление с objectdb

1

Следующий код:

    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: 1001

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

Теги:
jpa
objectdb

1 ответ

0

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

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

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

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню