Wyłącz buforowanie w JPA (eclipselink)

Chcę użyć JPA (eclipselink), aby pobrać dane z mojej bazy danych. Baza danych jest zmieniana przez wiele innych źródeł i dlatego chcę wrócić do bazy danych dla każdego znaleziska, które wykonuję. Przeczytałem kilka postów na temat wyłączania pamięci podręcznej, ale to nie wydaje się działać. Jakieś pomysły?

Próbuję wykonać następujący kod:

        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);

Jeden = = Dwa jest prawdą, podczas gdy ja chcę, żeby było fałszywe.

Próbowałem dodać każdy / wszystkie następujące do mojego wytrwałość.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"/>

Próbowałem również dodać adnotację @ Cache do samego encji:

@Cache(
  type=CacheType.NONE, // Cache nothing
  expiry=0,
  alwaysRefresh=true
)
Czy coś źle zrozumiałam?
Author: Lipis, 2010-05-11

7 answers

To zachowanie jest poprawne, w przeciwnym razie jeśli zmienisz obiekt pierwszy i obiekt drugi o różnych wartościach, będziesz miał problemy podczas ich utrzymywania. To, co się dzieje, to wywołanie load object two aktualizuje obiekt załadowany w pierwszym wywołaniu. Muszą wskazywać na ten sam obiekt, ponieważ są tym samym obiektem. Gwarantuje to, że nie można zapisać brudnych danych.

Jeśli do nich zadzwonisz.clear () pomiędzy dwoma wywołaniami, entity one powinny zostać odłączone Twoje sprawdzenie zwróci false. Jest jednak nie trzeba tego robić, Eclipse link jest w rzeczywistości aktualizowanie danych do najnowszych, co myślę, że jest to, co chcesz, ponieważ często się zmienia.

Na marginesie, jeśli chcesz zaktualizować te dane za pomocą JPA, musisz uzyskać pesymistyczne blokady na encji, aby Podstawowe Dane nie mogły się zmienić w DB.

Będziesz musiał wyłączyć pamięć podręczną zapytań, a także opcje pamięci podręcznej usuwały tylko pamięć podręczną obiektów z odtwarzania, a nie pamięć podręczną zapytań, dlatego nie uzyskują nowych wyników:

W kodzie:

em.createNamedQuery("MyLocation.findMyLoc").setHint(QueryHints.CACHE_USAGE, CacheUsage.DoNotCheckCache).getResultList().get(0);

Lub w uporczywości.xml:

<property name="eclipselink.query-results-cache" value="false"/>
 35
Author: Justin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-05-11 13:20:57
final Query readQuery = this.entityManager.createQuery(selectQuery);
readQuery.setParameter(paramA, valueA);

// Update the JPA session cache with objects that the query returns.
// Hence the entity objects in the returned collection always updated.
readQuery.setHint(QueryHints.REFRESH, HintValues.TRUE);

entityList = readQuery.getResultList();
To mi pasuje.
 22
Author: Binu S,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-14 23:37:45

Zobacz,

Http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Caching

Dla tego samego Entitymanagera JPA zawsze wymaga, aby jeden = = dwa, więc jest to poprawne, bez względu na opcje buforowania (jest to bufor L1 lub bufor transakcyjny, który wymusza izolację transakcji i utrzymuje tożsamość obiektu).

Aby wymusić odświeżenie zapytania (i cofnięcie wprowadzonych zmian), możesz użyć podpowiedzi zapytania " eclipselink.refresh" = "true". Lub prawdopodobnie lepiej, Użyj nowego Entitymanagera dla każdego zapytania/żądania lub wywołaj clear () na swoim Entitymanagerze.

<property name="eclipselink.cache.shared.default" value="false"/>

Jest prawidłowym sposobem wyłączenia współdzielonej pamięci podręcznej (L2 cache). Usuń wszystkie inne ustawienia, ponieważ nie są poprawne i mogą powodować problemy.

EclipseLink domyślnie nie utrzymuje bufora zapytań, więc te ustawienia nie będą miały wpływu. CacheUsage również nie jest poprawny, nie używaj tego (służy do zapytań w pamięci).

 10
Author: James,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-05 14:12:44

Jeśli chcesz wyłączyć buforowanie bez uzyskania specyficznego dostawcy, możesz dodać adnotację do obiektu domeny za pomocą:

@Cacheable(false)

Oto przykład:

@Entity
@Table(name="SomeEntity")
@Cacheable(false)
public class SomeEntity {
    // ...
}
 9
Author: diadyne,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-16 00:34:46

W przypadku ręcznej modyfikacji atrybutów obiektu, na przykład MyLocation. Powyższa sztuczka (CACHE_USAGE=CacheUsage.DoNotCheckCache, lub eclipselink.query-results-cache=false) nie wydaje się działać tak, jak próbowałem.

Więc próbowałem ustawić kolejną podpowiedź, która jest eclipselink.refresh, true. to działa. Chodzi mi o to, że ręcznie zmienione atrybuty są pobierane.

Więc jak rozumiem, powyższa sztuczka tylko upewnić się, że dostaje poprawne obiekty. Jeśli jednak obiekty zostały już buforowane, eclipselink zwraca je bez sprawdzania świeżości zawartość obiektów. Tylko wtedy, gdy podpowiedź eclipselink.refresh jest ustawiona na true, obiekty te zostaną odświeżone, aby odzwierciedlić najnowsze wartości atrybutów.

 3
Author: Robin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-16 12:33:21

Wiem, że ten post może być stary, ale piszę dla innych, którzy potrzebują pomocy. Miałem ten problem i w końcu go rozwiązałem tym kodem:

em.createNamedQuery("findAll").setHint(QueryHints.CACHE_RETRIEVE_MODE, CacheRetrieveMode.BYPASS).getResultList();
To działa naprawdę dobrze. I widzimy w javadoc of the BYPASS enum, jest napisane, że:

Omiń pamięć podręczną: Pobierz dane bezpośrednio z bazy danych.

Powinienem zauważyć, że używam Weblogic 12C i TopLink jako implementacji JPA.

 3
Author: AliReza19330,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-27 06:07:51

Pamięć podręczna pierwszego poziomu jest domyślnie włączona i nie można jej wyłączyć. tzn. brak ustawień w Twoim uporczywości.plik xml wyłączy pamięć podręczną pierwszego poziomu.

Możesz wyczyścić wszystkie obiekty menedżera encji tylko przez wywołanie

entityManager.clear()

Spowoduje to, że kolejne zapytania trafią do bazy danych (za pierwszym razem), a następnie obiekty zostaną ponownie zapisane w pamięci podręcznej

Możesz wymusić przejście każdego zapytania bezpośrednio do bazy danych przez wywołanie

query.setHint("javax.persistence.cache.storeMode", CacheStoreMode.REFRESH);
 2
Author: Michael,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-08 10:49:43