Стратегия удаления кэша Hibernate Query - PullRequest
0 голосов
/ 17 ноября 2010

Для простого сценария 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

1 Ответ

0 голосов
/ 17 ноября 2010

настроили спящий режим на использование кеша второго уровня, так как вы используете ehcache для достижения кеша второго уровня. потому что, если вы используете это, то вы можете добавить время, после которого кеш будет обновляться из базы данных (синхронизировать с базой данных),

это то, что я использую в своем приложении, может быть, это может помочь вам ..

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

по истечении времени истечения кеш будет автоматически обновляться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...