переживает следующий кажущийся недокументированный вопрос, и я хочу, чтобы понять, еслиСпящий режим 2-го уровня кэш-объекты, которые lazy = false, приводят к по умолчанию fetch = join, документированы ли они где-нибудь?
- я сделал что-то неправильно
- ли кто-нибудь столкнуться с таким же вопросом?
- Действительно ли это не документировано нигде? или я что-то пропустил?
Поведение это Предположим следующее отображение
<class name="org.sample.Foo" table="foo">
...
<many-to-one name="bar" class="org.sample.Bar"/>
</class>
<class name="org.sample.Bar" table="bar" lazy="false">
...
</class>
Во-первых, в качестве фона, Hibernate значение по умолчанию для выборки атрибут отношения многие-к-одному должна быть "выберите ", это, по крайней мере, то, что документировано (я добавлю ссылку здесь, когда найду его)
Однако это, по-видимому, верно только в том случае, если ссылочный класс lazy =" true "!
так очевидно выше отображение переводится на это (потому что Bar ленив = «ложь»):
<class name="org.sample.Foo" table="foo">
...
<many-to-one name="bar" class="org.sample.Bar" *fetch="join" />
</class>
<class name="org.sample.Bar" table="bar" lazy="false">
...
</class>
Теперь, почему это будет проблемой? вместо 2 выбирает, Hibernate будет загружать нелокальную ссылку в одном элементе с его «родительским» (загружать Foo с помощью Bar в одном select)
Это действительно имеет смысл, поскольку объект не ленив, почему бы не загрузить Это?Ответ таков: что произойдет, если Bar находится в кеше второго уровня?
<class name="org.sample.Foo" table="foo">
...
<many-to-one name="bar" class="org.sample.Bar" *fetch="join" />
</class>
<class name="org.sample.Bar" table="bar" lazy="false">
<cache usage="transactional" />
...
</class>
И ответ на это - ничего не меняется!
Очевидно, можно предположить, что Hibernate достаточно умен, чтобы понять, что объекты этого типа не должны быть загружены, но поскольку выбор по умолчанию был изменен с select на join, у Hibernate нет выбора (вы не можете присоединиться к реальная таблица с кэшем 2-го уровня, пока)
так Hibernate делает то, что он сказал, и использует объединение для извлечения объекта из базы данных, где она уже находится в кэше 2-го уровня
решение, которое я нашел это буквально изменить отображение на fetch = "select"
Теперь, когда второй выбор для бара собирается перейти, Hibernate понимает, что он не должен идти в базу данных и извлекает его из кеша. и только 1 запрос будет выполнен (после разминки)
Поведение выборки зависит от API, который вы используете для запроса объектов. Вы используете API HQL или Criteria? – skaffman
Ни один простой session.load (Foo.class, id) –