Проблемы с кэшированием коллекций с Hibernate и EhCache - PullRequest
3 голосов
/ 20 августа 2011

, как предполагает тема, у меня возникли некоторые проблемы с Hibernate и EhCache.

Я использую Hibernate с mySql и EhCache в Resteasy-приложении.

Модель: Естьэто несколько сущностей, некоторые отношения один-ко-многим и некоторые отношения один-к-одному.

  • Измерение
    • информации заголовка (один-к-одному)
    • content (один-к-одному)
      • мест (один-к-одному (этот элемент мне нужен из-за его метаданных)
        • place (коллекция с объектами-местами) (one-to-мани ленивый)
          • мера (коллекция с сущностями меры) (ленивый один-ко-многим)
          • тайм-код (коллекция с тайм-кодом тайм-кода (ленивый один ко многим)
            • мера (сбор с единицами измерения) (один-ко-многим ленивый)

Проблема: я пытаюсь получить все свои данные в запросе типа createQuery("from Measuring c").list(). Теперь есть два способа кэширования результата: Querycache и 2nd-level-cache.

кеш запросовЯ буду только кэшировать выбор для объекта измерения, не говоря уже о том, что это не то поведение, которого я ожидал.Я хочу, чтобы кеш запросов кешировал все sql-операторы.Есть ли способ заставить это работать?

Я активировал кеш для всех сущностей.Кэш 2-го уровня будет кэшировать элементы, но не ударит их снова (хорошо, но только измеряющий элемент);Через несколько небольших мыслей я понял, что мне нужно кэшировать коллекции, чтобы кеш знал, какие элементы принадлежат друг другу.

Что ж, активация кэшей для всех коллекций «один ко многим» прекрасно работает в случае извлечения всех данных.как первый запрос кеша.Но если бы не было проблемы, я бы не написал это.Запрос места по одному из его полей в качестве первого действия кеша заставит кеш делать то, что он должен: он кеширует запрошенные данные, что означает измеряющий объект (фактически в базе данных есть только один), информация заголовка, контентс местами-элементом и найденным местом с его подэлементами.Запросы в другое место также отлично работает.Теперь я хочу получить все элементы (запрос, упомянутый выше), но я получаю только уже запрошенные.Похоже, что hibernate запрашивает только кэш, если инструкция не содержит критериев выбора.Это кажется маленькой проблемой при кэшировании коллекций.

Итак, мне нужно либо получить кеш запросов для кэширования всех операторов, либо кеш 2-го уровня, извлекающий всю коллекцию, если она запрошена, но уже была выполнена конкретная.

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

Ну, я могу представить, что в моих запросах есть некоторые ошибки.Итак, вот оба упомянутых запроса:

Получить все данные: createQuery("from Measuring c").setCacheable(true).list()

Получить данные с конкретным местом: createQuery("from Measuring measuringElement join fetch measuringElement.content contentElement join fetch contentElement.places placesElement join fetch placesElement.places placeElement WHERE placeElement.name = '" + name +"'").setCacheable(true).list().

Кто-нибудь может мне помочь?

Большое спасибо заранее и всего наилучшего

Ответы [ 2 ]

5 голосов
/ 21 августа 2011

Ваш вопрос очень сложен для понимания, поэтому я просто объясню, как работают кэши.

Вы можете кэшировать три вещи:

  • сущностей
  • коллекции сущностей (т. е. ассоциации ToMany)
  • запросы

Кэш сущностей будет попадать при использовании get или load и при переходе от другой сущности к кешированной сущности через ToOneассоциация.Только поля сущности кэшируются.Не ассоциации ToMany.

Кэш коллекций будет поврежден при навигации по кэшированной ассоциации ToMany.Кеш хранит только идентификаторы сущностей в коллекции.Hibernate попытается получить все объекты коллекции по одному, используя кэшированные идентификаторы.Таким образом, чтобы быть эффективными, целевые объекты также должны находиться в кеше сущностей.

При выполнении кешированного запроса кеш запросов будет задействован.Когда запрос возвращает экземпляры сущностей (например, два запроса вашего вопроса), в кеше запросов хранятся только идентификаторы корневых сущностей, возвращаемых запросом.Это не кэширует весь результат.Hibernate попытается получить все объекты коллекции по одному, используя кэшированные идентификаторы.Таким образом, чтобы быть эффективными, целевые объекты должны также находиться в кэше объектов.

Итак, если вы хотите выполнить запрос, возвращающий объект со всеми его рекурсивными рекурсивными действиями, вы должны сделать запрос кэшируемым, сделать ToManyассоциации кэшируются, и делают каждую сущность графа кэшируемой.

0 голосов
/ 27 августа 2014

Мне пришлось сделать

<set lazy="false" ...>

или выполнить итерацию по коллекции, иначе коллекция не написана на Ehcache.

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