51 votes

Désactiver la mise en cache dans JPA (eclipselink)

Je veux utiliser JPA (eclipselink) pour obtenir des données de ma base de données. La base de données est modifié par un certain nombre d'autres sources, et je veux donc revenir à la base de données pour tous les trouver, je les exécuter. J'ai lu un certain nombre de messages sur la désactivation du cache mais cela ne semble pas fonctionner. Des idées?

Je suis en train d'exécuter le code suivant:

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

un==deux est vraie alors je veux qu'il soit faux.

J'ai essayé d'ajouter chaque/tout ce qui suit à mon 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"/>

J'ai aussi essayé d'ajouter le @Cache annotation à l'Entité elle-même:

@Cache(
  type=CacheType.NONE, // Cache nothing
  expiry=0,
  alwaysRefresh=true
)

Suis-je un malentendu quelque chose?

44voto

Justin Points 1781

Ce comportement est correct, sinon, si vous changez d'objet de l'un et de l'objet de deux valeurs différentes, vous aurez des problèmes lors de la persistance d'eux. Ce qui se passe est l'appel à la charge de l'objet de deux mises à jour de l'entité chargée dans le premier appel. Ils doivent pointer vers le même objet dans la mesure où ils SONT le même objet. Cela garantit que les données ne peuvent pas être écrites.

Si vous appelez de l'em.clear() entre les deux appels, une entité doit se détacher votre chèque sera de retour faux. Il n'est cependant pas nécessaire de le faire, eclipse lien est en fait la mise à jour de vos données à la dernière qui, je suppose est ce que vous voulez, car il change souvent.

Sur une note de côté, si vous souhaitez mettre à jour ces données en utilisant JPA, vous devez être obtenir pessimiste serrures sur l'Entité de sorte que les données sous-jacentes ne peut pas changer dans la base de données.

Vous aurez besoin de désactiver la mise en cache de requêtes ainsi que vos options de mise en cache ont été juste de retirer le cache d'objets du jeu ne le cache de requête, c'est pourquoi vous n'obtenez pas les résultats:

Dans votre code:

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

Ou dans persistence.xml:

<property name="eclipselink.query-results-cache" value="false"/>

30voto

Binu S Points 141
 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();
 

Cela fonctionne pour moi.

13voto

James Points 18355

Voir,

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

Pour la même EntityManager JPA nécessite toujours que un==les deux, alors c'est correct, pas question de vos options de mise en cache (c'est le cache L1, transactionnelles ou de cache, qui applique votre isolation de transaction et maintient l'identité de l'objet).

Pour forcer la requête de rafraîchissement (et de revenir tous les changements que vous avez fait), vous pouvez utiliser l'indicateur de requête "eclipselink.actualiser"="true". Ou sans doute mieux, utiliser un nouveau EntityManager pour chaque requête/demande, ou appelez clear() sur votre EntityManager.

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

Est la bonne façon de désactiver la mémoire cache partagée (cache L2). Veuillez supprimer tous vos autres paramètres ne sont pas corrects, et peuvent causer des problèmes.

EclipseLink de ne pas maintenir un cache de requêtes par défaut, de sorte que ces paramètres n'ont aucun effet. CacheUsage est pas non plus correct, ne pas l'utiliser (il est dans la mémoire de l'interrogation).

4voto

Robin Points 114

Si manuellement modifier les attributs de l'objet, par exemple MyLocation. L'astuce ci-dessus (CACHE_USAGE=CacheUsage.DoNotCheckCacheou eclipselink.query-results-cache=false) ne semble pas fonctionner comme je l'ai essayé.

J'ai donc essayé de mettre un autre indice qui est eclipselink.refresh, pour true. puis il travaille. Je veux dire le changer manuellement les attributs récupérés.

Donc si je comprends bien, l'astuce ci-dessus uniquement à assurer le il obtient les objets corrects. Toutefois, si les objets ont été déjà mis en cache, eclipselink juste les renvoie sans vérifier la fraîcheur du contenu des objets. Seulement lorsque l'indicateur eclipselink.refresh est définie à l' true, ces objets seront actualisés pour refléter les dernières valeurs d'attribut.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X