Я хочу использовать JPA (eclipselink) для получения данных из моей базы данных. База данных изменяется многими другими источниками, и я поэтому хочу вернуться к базе данных для каждой находки, которую я выполняю. Я прочитал много сообщений при отключении кэша, но это, кажется, не работает. Какие-либо идеи?
Я пытаюсь выполнить следующий код:
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("default");
EntityManager em = entityManagerFactory.createEntityManager();
MyLocation one = em.createNamedQuery("MyLocation.findMyLoc").getResultList().get(0);
MyLocation two = em.createNamedQuery("MyLocation.findMyLoc").getResultList().get(0);
System.out.println(one==two);
один == два верно, в то время как я хочу, чтобы это было ложью.
Я попытался добавить каждого/всего следующее к моему persistence.xml
<property name="eclipselink.cache.shared.default" value="false"/>
<property name="eclipselink.cache.size.default" value="0"/>
<property name="eclipselink.cache.type.default" value="None"/>
Я также попытался добавить @Cache аннотацию к самому Объекту:
@Cache(
type=CacheType.NONE, // Cache nothing
expiry=0,
alwaysRefresh=true
)
Я неправильно понимаю что-то?
Это правильное поведение, иначе, если вы измените объект один и объект два на разные значения, у вас возникнут проблемы при их сохранении. Происходит то, что при вызове загрузки объекта два обновляет объект, загруженный при первом вызове. Они должны указывать на один и тот же объект, поскольку ЯВЛЯЕТСЯ одним и тем же объектом. Это гарантирует невозможность записи грязных данных.
Если вы вызываете em.clear () между двумя вызовами, объект один должен быть отсоединен, ваша проверка вернет false. Однако в этом нет необходимости, ссылка eclipse фактически обновляет ваши данные до последней версии, что, как я полагаю, - это то, что вы хотите, поскольку она часто меняется.
Кстати, если вы хотите обновить эти данные с помощью JPA, вам нужно будет установить пессимистические блокировки на Entity, чтобы базовые данные не могли измениться в БД.
Вам нужно будет отключить кеш запросов, так как ваши параметры кеширования просто удаляли кеш объектов из воспроизведения, а не кеш запросов, поэтому вы не получаете новых результатов:
В вашем коде:
em.createNamedQuery("MyLocation.findMyLoc").setHint(QueryHints.CACHE_USAGE, CacheUsage.DoNotCheckCache).getResultList().get(0);
Или в persistence.xml:
<property name="eclipselink.query-results-cache" value="false"/>
При ручной модификации атрибутов объекта, например MyLocation. Вышеуказанный трюк (CACHE_USAGE=CacheUsage.DoNotCheckCache
, или eclipselink.query-results-cache=false
) не работает, как я ни пытался.
Поэтому я попытался установить другой хинт, который eclipselink.refresh
, в true
. тогда он работает. Я имею в виду, что измененные вручную атрибуты извлекаются.
Итак, как я понимаю, вышеописанный трюк только гарантирует получение правильных объектов. Однако, если объекты уже были кэшированы, eclipselink просто возвращает их, не проверяя свежесть содержимого объектов. Только когда подсказка eclipselink.refresh
установлена в true
, эти объекты будут обновлены, чтобы отразить последние значения атрибутов.