J'ai une application Web utilisant JPA. Ce gestionnaire d’entités garde un tas d’entités et du coup je mets à jour la base de données de l’autre côté. J'utilise MySQL et j'utilise PhpMyAdmin et modifie une ligne.
Comment demander au gestionnaire d'entités de resynchroniser, par exemple oublier toutes les entités en cache?
Je sais qu'il existe une méthode refresh(Object)
, mais y a-t-il une possibilité de faire refreshAll()
ou quelque chose qui en résulte?
C’est sûr que c’est une opération coûteuse mais si cela doit être fait.
entityManager.getEntityManagerFactory().getCache().evictAll()
Refresh
est différent car il modifie votre objet. Cette ligne ne contiendra que empty the cache
; par conséquent, si vous récupérez des objets modifiés en dehors du gestionnaire d'entités, une requête de base de données réelle sera exécutée au lieu d'utiliser la valeur obsolète cached
.
J'ai eu un problème similaire et la ligne evictAll()
ci-dessus a fonctionné pour moi.
Sinon, l'annotation @Cache
sur la classe d'entité a également fonctionné, avec l'avantage de pouvoir contrôler les paramètres de mise en cache:
@Cache(coordinationType=CacheCoordinationType.INVALIDATE_CHANGED_OBJECTS)
Voir: http://wiki.Eclipse.org/EclipseLink/Examples/JPA/Caching
Eh bien, pour certaines personnes (comme moi) qui ont essayé d'ajouter factory.getCache (). EvictAll (); et ne fonctionne pas et utilise JPA + Hibernate, pour actualiser une requête, ajoutez l'indicateur org.hibernate.cacheMode àIGNORE. Exemple:
em.createNamedQuery("SomeEntity.SomeNamedQuery")
.setHint("org.hibernate.cacheMode", "IGNORE")
.getResultList();
Si vous utilisez EclipseLink au lieu d’Hibernate, l’indice est le suivant:
em.createNamedQuery("SomeEntity.SomeNamedQuery")
.setHint(QueryHints.REFRESH, true)
.getResultList();
cache.evictAll ne fonctionne pas pour moi. Donc, pour récupérer les données envoyées à partir d'une autre application, je peform:
em.getTransaction().begin();
em.getTransaction().commit();
Après cela, ma requête de recherche récupère les données actualisées. Je ne sais pas si c'est une solution très sûre mais cela fonctionne correctement.
Lorsque vous lisez un objet dans un EntityManager, il fait partie du contexte de persistance et le même objet reste dans EntityManager jusqu'à ce que vous le supprimiez () et obteniez un nouveau EntityManager. Ainsi, si vous mettez à jour la base de données, EntityManager ne verra pas la modification, sauf si vous appelez refresh () sur l'objet ou désactivez () EntityManager. Cela n'a rien à voir avec le cache partagé (L2) ou le contexte de persistance (L1). Si vous utilisez également un cache partagé et mettez à jour la base de données directement, votre cache partagé sera obsolète. Vous devez actualiser () l'objet ou le marquer comme non valide pour l'actualiser à la prochaine interrogation.
Le code doit suivre le chemin comme . DETACH RAFRAICHIR FUSIONNER FLUSH