2010-11-17 4 views
0

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

Répondre

0

ont configuré l'hibernation pour utiliser le cache de second niveau, comme vous utilisez ehcache pour atteindre le cache l2. parce que si vous utilisez que, vous pouvez ajouter le temps après lequel cache sera mis à jour la base de données (synchronisation avec la base de données),

ce que je me sers dans ma demande, peut-être cela peut vous aider ..

<defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true"/> 

Après l'expiration, le cache sera automatiquement mis à jour.

Questions connexes