Вопрос

У меня есть объект домена Hibernate, который загружается разными частями приложения.Иногда выгодно лениво загружать каждую ассоциацию, а в других случаях лучше загрузить все целиком за одно объединение.В качестве, надеюсь, счастливого компромисса, который я нашел:

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

hibernate.default_batch_fetch_size:

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

Я тоже вижу:

hibernate.jdbc.fetch_size:

Ненулевое значение определяет размер выборки JDBC (вызывает оператор.setFetchSize()).

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

Если все содержимое коллекции уже содержится в кэше, будет ли оно по-прежнему выполнять запросы на выборку при доступе к коллекции?

Спасибо.

Это было полезно?

Решение

Сегодня я провел много исследований и смог найти ответ на свой собственный вопрос.Я просматривал код гибернации, и поток выглядит следующим образом:

Инициализирована ли коллекция?

  • Нет?Выполните пакетную выборку (элементы, полученные с помощью пакетной выборки, помещаются в кэш).
  • Да?Поищите в кэше конкретный элемент, если его там нет, выполните пакетную выборку.

Таким образом, если элемент в коллекции, которую вы ищете, НАЙДЕН в кэше, то пакетная выборка не выполняется.Если элемент НЕ найден в кэше второго уровня, то выполняется пакетная выборка, НО она будет выполнять выборку пакетных элементов НЕЗАВИСИМО от того, находятся ли пакетные элементы в кэше.


----- ПРИМЕР 1 -----

Хорошее:

(Три предмета в коллекции - размер партии 3) Первый заход:

  • collection.GetItem(0) - Нет кэша | пакетная выборка 3 элементов
  • collection.GetItem(1) - Загружается с помощью пакетной выборки
  • collection.GetItem(2) - Загружается с помощью пакетной выборки

Сейчас, где-нибудь в другом месте, позже по времени:

  • collection.GetItem(0) - Попадание в кэш
  • collection.GetItem(1) - Попадание в кэш
  • collection.GetItem(2) - Попадание в кэш

----- ПРИМЕР 2 -----

Плохое:

(Три элемента в коллекции - размер пакета 3)

В этом случае элемент с индексом 0 был удален из кэша, потому что, возможно, кэш был заполнен и элемент был удален, или элемент устарел или простаивал.

  • collection.GetItem(0) - Не в кэше, Поэтому сделайте пакет из 3 (выберите *, где id в (?, ?, ?))
  • collection.GetItem(1) - Уже в кэше (в любом случае заменен на пакетную выборку)
  • collection.GetItem(2) - Уже в кэше (в любом случае заменен на пакетную выборку)

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

http://opensource.atlassian.com/projects/hibernate/browse/HHH-1775

Голосуйте за это!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top