Pour un simple post-Tag @ManyToMany scénario comme celui-ci @ManyToMany inconsistent data on both side problemHibernate Interrogation stratégie d'expulsion de cache
Il semble 2ème cache de niveau qu'Hibernate ne connaît pas le temps de mettre à jour la fonction d'agrégation (ex: nombre) comme celui-ci un:
public int getPostCountByTag(Tag tag)
{
Session session = (Session) em.getDelegate();
Criteria c = session.createCriteria(Post.class);
c.createCriteria("tags")
.add(Restrictions.eq("id", tag.getId()));
c.setProjection(Projections.rowCount());
c.setCacheable(true);
int num = ((Long) c.uniqueResult()).intValue();
return num;
}
Et mise en veille prolongée ne sait pas non plus, il est temps de mettre à jour une liste comme celle-ci:
public List<Post> getPostsByTag(Tag tag, int start, int count)
{
Session session = (Session) em.getDelegate();
Criteria c = session.createCriteria(Post.class);
c.createCriteria("tags")
.add(Restrictions.eq("id", tag.getId()));
c.addOrder(Order.desc("created")); break;
c.setFirstResult(start);
c.setMaxResults(count);
c.setCacheable(true);
return c.list();
}
Chaque fois que j'ajouter/supprimer une balise vers/depuis un poste, ces comptes et listes restent inchangés. Je sais peut-être que c'est parce qu'ils sont mis en cache par c.setCacheable(true)
, et je dois expulser manuellement le cache ou définir le délai d'expiration plus court. Mais, je me demande s'il existe un moyen meilleur/plus intelligent pour hiberner la détection automatique du temps d'éviction du cache?
Dans l'exemple, seules deux méthodes sont affectées par l'ajout/le retrait de tag, mais au fur et à mesure que les méthodes se développent, la gestion de l'expulsion du cache devient très lourde et source d'erreurs. par exemple:
addTag(Post post , Tag tag)
{
post.addTag(tag);
postDao.update(post);
EntityManagerFactoryUtils.getTransactionalEntityManager(emf).flush();
evict_cache_in_getPostsByTag();
evict_cache_in_getPostCountByTag();
evict_cache_in_getPostsByTagAndBlah();
evict_cache_in_getPostsByTagAndBlahBlah();
evict_cache_in_getPostsByTagAndBlahBlahBlah();
}
removeTag(Post post , Tag tag)
{
post.removeTag(tag);
postDao.update(post);
EntityManagerFactoryUtils.getTransactionalEntityManager(emf).flush();
evict_cache_in_getPostsByTag();
evict_cache_in_getPostCountByTag();
evict_cache_in_getPostsByTagAndBlah();
evict_cache_in_getPostsByTagAndBlahBlah();
evict_cache_in_getPostsByTagAndBlahBlahBlah();
}
Ceci est terrible !!! Je voudrais savoir comment résoudre ce problème n x m
? (N est 2 (add/remove)
, m est 5 (evicts)
, dans cet exemple)
Par ailleurs, je trouve cache.evictQueryRegions()
de veille prolongée semble fonctionne pas du tout. Je dois donner manuellement un nom à chaque cache de requête (région de cache), et spécifier quelle région de cache à expulser par cache.evictQueryRegion("getTagPostsCount");
, Ai-je manqué quelque chose? ou est-ce le bug d'Hibernate? (mise à jour: après la mise à niveau vers Hibernate 3.6.0.Final, le problème est résolu, il semble que ce soit le bogue de 3.5.6)
Hibernate 3.5.6-Final, hibernate-jpa-2.0, ehcache-1.5.0, Spring-3.0.4