Гибернация: размер_пакета? Кэш второго уровня?

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

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

hibernate.default_batch_fetch_size:

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

Я также вижу:

hibernate.jdbc.fetch_size:

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

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

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

Спасибо.


person davidemm    schedule 25.08.2009    source источник
comment
Теперь это то, что я тоже хотел бы знать ответ.   -  person Zoidberg    schedule 25.08.2009
comment
Пометьте мой вопрос :-)   -  person davidemm    schedule 25.08.2009


Ответы (1)


Сегодня я провел много исследований и смог найти ответ на свой вопрос. Я просматривал код Hibernate, и поток выглядит так:

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

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

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


----- ПРИМЕР 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 (выберите *, где идентификатор в (?,?,?))
  • collection.getItem(1) - Уже в кеше (все равно заменено на пакетную выборку)
  • collection.getItem(2) - Уже в кеше (все равно заменено на пакетную выборку)

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

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

Голосуйте!

person davidemm    schedule 26.08.2009