Я испытываю следующую по-видимому недокументированную проблему, и я хочу понять если
Поведение, это Принимает следующее отображение
<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>
Во-первых, как фон, Будьте в спящем режиме, значение по умолчанию для атрибута выборки на many-one отношении должно быть "выбором", это, по крайней мере, что документируется (я добавлю ссылку здесь, когда я найду его),
Однако это по-видимому только верно, если класс, на который ссылаются, ленив = "верный"!
таким образом, по-видимому, вышеупомянутое отображение переводится в это (потому что Панель ленива = "ложь"):
<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 выбирает, Будьте в спящем режиме, загрузится, не ленивая ссылка в единственном выборе с помощью его "родителя" (загрузите Нечто Панелью в единственном выборе),
это на самом деле имеет смысл, так как объект не ленив, почему бы не загрузить его?
Ответ - это: что происходит, если Панель находится в 2-м кэше уровня?
<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>
И ответ на это - ничто не изменяется!
По-видимому, можно было бы принять, в спящем режиме, достаточно умно, чтобы понять, что объекты этого типа не должны быть загружены, но так как выборка по умолчанию была изменена от выбора до соединения, Будьте в спящем режиме, не имеет выбора (Вы не можете присоединиться к реальной таблице с 2-м кэшем уровня, еще),
поэтому Будьте в спящем режиме, делает то, что это сказано и использует соединение для выборки объекта от базы данных, где это уже находится в 2-м кэше уровня
Решение, которое я нашел, состоит в том, чтобы буквально изменить отображение на выборку = "выбор"
Теперь то, когда второй выбор для Панели собирается пойти, Быть в спящем режиме, понимает, что это не должно переходить к базе данных и выбирает его от кэша. и только 1 запрос выполнится (после прогрева)
Я столкнулся с той же проблемой, и обнаружил, что пометил все отношения между собой, которые будут кэшироваться как fetch="select"
. В момент построения запроса Hibernate не может знать, находится ли запрашиваемый экземпляр Bar в кэше второго уровня или нет (предполагая, что Foo не находится в кэше).