Hibernate 2 -й уровень кэша кеша, которые ленивы = false, приводят к поэмплэк = присоединение, это задокументировано где -нибудь?

StackOverflow https://stackoverflow.com/questions/1968767

Вопрос

Я испытываю следующую, по -видимому, недокументированную проблему, и я хочу понять, если

  1. Я сделал что -то не так
  2. Кто -нибудь столкнулся с той же проблемой?
  3. Это действительно нигде не задокументировано? Или я что -то пропустил?

Поведение - это предполагает следующее отображение

<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 для принести Атрибут на отношение для многих к одному должно быть »Выбрать", Это, по крайней мере, то, что задокументировано (я добавлю ссылку здесь, когда найду ее)

Тем не менее, это, по -видимому, верно только в том случае, если ссылочный класс ленивый = "true"!

По -видимому, вышеупомянутое отображение переводится в это (потому что бар ленивый = "false"):

<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 с помощью стержня в одном выборе)

Это на самом деле имеет смысл, поскольку объект не ленив, почему бы не загрузить его?

Ответ такого: что происходит, если бар находится во втором уровне кэша?

<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 запрос будет выполнен (после разминки)

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

Решение

Я столкнулся с той же проблемой и обнаружил, что отмечаю все отношения, которые будут кэшированы как fetch="select". Анкет В то время, когда запрашивается запрос, Hibernate не может знать, находится ли запрашиваемый экземпляр Bar в кэше второго уровня или нет (при условии, что Foo не в кэшировании).

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