Я провел много исследований сегодня и смог найти ответ на свой вопрос. Я просматривал код 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 (выберите * где id в (?,?,?))
- collection.getItem (1) - в кэше уже (заменено пакетным извлечением в любом случае)
- collection.getItem (2) - в кэше уже (заменено пакетным извлечением в любом случае)
Таким образом, компромисс здесь заключается в том, что у вас будет меньше вызовов SQL из-за пакетной обработки, но вы будете чаще пропускать кеш. Открыт тикет, в котором пакетный взгляд просматривается в кэше второго уровня, прежде чем он поступит в базу данных.
http://opensource.atlassian.com/projects/hibernate/browse/HHH-1775
Проголосуйте!