Старые данные возвращаются при использовании JPQL createQuery - PullRequest
3 голосов
/ 27 ноября 2011

Использование JPA / Eclipse TopLink.

Я обновляю таблицу (используя createNativeQuery), как показано ниже:

Query query = em.createNativeQuery("UPDATE Products SET productName='" + p.getProductName() + "',productVendor='" + p.getProductVendor() + "',productDescription='" + p.getProductDescription() + "',quantityInStock=" + p.getQuantityInStock() + ",buyPrice =" + p.getBuyPrice() + ",msrp=" + p.getMsrp() + " WHERE productCode='" + p.getProductCode() + "'");
query.executeUpdate();

Обновление отражается в БД (MySQL)

Для извлечения (используя createQuery), как показано ниже:

Query query1 = em.createQuery("SELECT p from Products p where p.productCode='"+searchTerm+"'");
return query1.getResultList();

Однако возвращаемый ResultList всегда представляет собой данные перед обновлением.Но когда я использую createNativeQuery вместо createQuery, возвращаются последние обновленные данные.В чем может быть возможная ошибка метода createQuery?

1 Ответ

6 голосов
/ 27 ноября 2011

когда вы используете пакетное обновление или собственные запросы, вы обходите кэш первого уровня. Toplink не может знать, что сущности, которые у него уже есть в кеше первого уровня, были изменены. Поэтому диспетчер сущностей должен быть очищен, чтобы запрос возвратил обновленные объекты.

Но, пожалуй, лучше всего избегать пакетных обновлений. Ваш первый запрос может быть заменен запросом JPQL, который загружает продукт с заданным кодом, а затем просто обновляет сущность Product. Даже если вы сохраните запрос на обновление, он может быть написан на JPQL, а не на SQL (но у вас все равно будет проблема).

Наконец, ваши запросы должны использовать параметры, чтобы избежать инъекций и убедиться, что все правильно экранировано:

Query query1 = em.createQuery("SELECT p from Products p where p.productCode = :searchTerm);
query1.setParameter("searchTerm", searchTerm);
return query1.getResultList();
...