2011-04-29 19 views
25

Tengo una aplicación web usando JPA. Este administrador de entidades guarda un montón de entidades y de repente actualizo la base de datos desde el otro lado. Yo uso MySQL y uso PhpMyAdmin y cambio alguna fila.Actualización de EntityManager

Cómo decirle al administrador de entidades que vuelva a sincronizar, p. Ej. ¿olvidó todas las entidades en el caché?

Sé que hay refresh(Object) método, pero ¿hay alguna posibilidad de cómo hacer refreshAll() o algo así como resultado de esto?

Es seguro que esto es una operación costosa, pero si tiene que hacerse.

Respuesta

29
entityManager.getEntityManagerFactory().getCache().evictAll() 

Refresh es algo diferente ya que modifica su objeto. Esta línea solo tendrá empty the cache, de modo que si recupera objetos cambiados fuera del administrador de entidades, hará una consulta de base de datos real en lugar de usar el valor obsoleto cached.

+1

salvó mi tiempo. Muchas gracias !! –

+1

Sé que tengo un par de años, pero quería aportar mis dos centavos. No estoy exactamente seguro de que esto pueda llamarse la respuesta. evictAll() funciona en el escenario donde desea que los datos nuevos sean persistentes/fusionados para ignorar lo que se almacena en caché y forzar la actualización/inserción de la base de datos. Sin embargo, evictAll() NO funciona (al menos para mí) en el escenario donde primero la base de datos back-end cambia un valor y ENTONCES espera que el cambio aparezca cuando se extrae del almacén de datos. En mi experiencia, el caché aún anula lo que se modificó en el back-end. –

7

Tuve un problema similar y la línea anterior evictAll() funcionó para mí.

Alternativamente, el @Cache anotación en la clase de entidad trabajó también, con la ventaja de ser capaz de controlar los parámetros de almacenamiento en caché:

@Cache(coordinationType=CacheCoordinationType.INVALIDATE_CHANGED_OBJECTS) 

Ver: http://wiki.eclipse.org/EclipseLink/Examples/JPA/Caching

2

Bueno, para algunas personas (como yo) que intentó agregar factory.getCache(). evictAll(); y no funciona, y se utilizan JPA + Hibernate, para actualizar una consulta, agregue la sugerencia org.hibernate.cacheMode a IGNORE. Ejemplo:

em.createNamedQuery("SomeEntity.SomeNamedQuery") 
    .setHint("org.hibernate.cacheMode", "IGNORE") 
    .getResultList(); 
1

cache.evictTodo no funciona para mí. Así que para recuperar datos empujados desde otra aplicación, que peform:

em.getTransaction().begin(); 
em.getTransaction().commit(); 

Después de eso, mi encontrar consulta recupera los datos actualizados. No sé si es una solución muy segura pero funciona correctamente.

2

Si está utilizando EclipseLink en lugar de Hibernate es la indirecta:

em.createNamedQuery("SomeEntity.SomeNamedQuery") 
.setHint(QueryHints.REFRESH, true) 
.getResultList(); 
Cuestiones relacionadas