Для простого сценария Post-Tag @ManyToMany, подобного этому @ ManyToMany противоречивые данные по обеим сторонам проблемы
Похоже, что кэш 2-го уровня hibernate не знает времени для обновленияфункция агрегации (например: count), подобная этой:
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;
}
И Hibernate также не знает, что пришло время обновить список, подобный этому:
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();
}
Каждый раз, когда ядобавить / удалить тег в / из сообщения, эти количество и список остаются неизменными.Я знаю, может быть, это потому, что они кэшируются c.setCacheable(true)
, и мне нужно вручную удалить кеш или установить время ожидания короче.
Но мне интересно, есть ли какой-нибудь лучший / более умный способ для автоматического определения режима гибернации?сроки выселения кеша?
В этом примере есть только два метода, на которые влияет добавление / удаление тега, но по мере роста методов управление вытеснением кэша станет очень громоздким и подверженным ошибкам.например:
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();
}
Это ужасно !!!
Интересно, как решить эту проблему n x m
?(n - 2 (add/remove)
, m - 5 (evicts)
, в данном примере)
Кстати, я обнаружил, что cache.evictQueryRegions()
в hibernate, похоже, НЕ работает вообще.Я должен вручную дать каждому кешу запросов имя (область кеша) и указать, какую область кеша нужно удалить с помощью cache.evictQueryRegion("getTagPostsCount");
. Я что-то пропустил?или это ошибка Hibernate?(обновлено: после обновления до Hibernate 3.6.0. Наконец, проблема решена, похоже, это ошибка 3.5.6)
Hibernate 3.5.6-Final, hibernate-jpa-2.0, ehcache-1.5.0, весна-3.0.4