Как помешать Hibernate активно загружать связанный объект - PullRequest
10 голосов
/ 21 октября 2008

У меня есть свойство объекта домена, которое объявлено в элементе «многие к одному». Основной синтаксис этого свойства выглядит следующим образом:

<many-to-one name="propertyName" class="propertyClass" fetch="select" not-found="ignore" lazy="proxy" />

Теперь идея состоит в том, чтобы Hibernate НЕ охотно получал это свойство. Может быть нулевым, поэтому игнорируемое значение установлено.

Но Hibernate после загрузки класса, содержащего эту ассоциацию, берет на себя загрузку фактического экземпляра класса (даже не прокси), когда загружается родительский класс. Поскольку некоторые свойства имеют размер более 1 МБ, они занимают много места в куче.

Если, однако, not-found установлен как исключение (или по умолчанию исключение), родительские классы, имеющие это свойство, загружают прокси!

Как я могу остановить спящий режим, чтобы не загружать прокси, но при этом разрешить этому свойству быть нулевым?

Я нашел lazy = no-proxy, но в документации говорится о какой-то модификации байт-кода и не вдаваться в подробности. Кто-нибудь может мне помочь?

Если это имеет значение, то это Java-версия Hibernate, и это по крайней мере версия 3 (я могу посмотреть реальную версию, если она поможет, но пока это Hibernate 3+).

Я не указывал ранее, но версия Java 1.4. Итак, аннотации Java не поддерживаются.

Ответы [ 6 ]

9 голосов
/ 21 октября 2008

Если другой конец ассоциации может иметь значение null , я считаю, что hibernate должен запросить конец ассоциации, чтобы определить, должен ли он использовать прокси-сервер (нет необходимости в прокси, если другой конец ноль ). Я не могу найти ссылку на это сейчас, но я помню, что читал это где-то.

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

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

Загрузка ленивых свойств требует Инструментарий байт-кода времени сборки! Если ваши постоянные занятия не улучшенный, Hibernate будет тихо игнорировать ленивые настройки свойств и падать вернуться к немедленному извлечению.

2 голосов
/ 23 февраля 2011

Убедитесь, что ваш класс не окончательный!

2 голосов
/ 22 августа 2009

Я нашел ленивый = без прокси, но документация говорит о каком-то модификация байт-кода и не идет в любые детали. Кто-нибудь может мне помочь из

Я предполагаю, что вы используете ANT для создания своего проекта.

<property name="src" value="/your/src/directory"/><!-- path of the source files -->
<property name="libs" value="/your/libs/directory"/><!-- path of your libraries -->
<property name="destination" value="/your/build/directory"/><!-- path of your build directory -->

<fileset id="applibs" dir="${libs}">
  <include name="hibernate3.jar" />
  <!-- include any other libraries you'll need here -->
</fileset>

<target name="compile">
  <javac srcdir="${src}" destdir="${destination}" debug="yes">
    <classpath>
      <fileset refid="applibs"/>
    </classpath>
  </javac>
</target>

<target name="instrument" depends="compile">
  <taskdef name="instrument" classname="org.hibernate.tool.instrument.javassist.InstrumentTask">
    <classpath>
      <fileset refid="applibs"/>
    </classpath>
  </taskdef>

  <instrument verbose="true">
    <fileset dir="${destination}">
      <!-- substitute the package where you keep your domain objs -->
      <include name="/com/mycompany/domainobjects/*.class"/>
    </fileset>
  </instrument>
</target>
0 голосов
/ 08 мая 2009

@ Мигель Пинг: Я думаю, что страница, на которую вы ссылаетесь, это [http://www.hibernate.org/162.html].. Насколько я понимаю, дополнительный SELECT необходим в случае взаимно-однозначной стороны, где отсутствует внешний ключ. Установка constrained="true" говорит Hibernate, что другая сторона всегда присутствует и никаких дополнительных SELECT не требуется.

Таким образом, для стороны "многие к одному", где находится внешний ключ, не должно быть необходимости выполнить другой SELECT, так как значение FK сообщает, присутствует ли другой конец или null. По крайней мере, я так понимаю.

Пока что по теории. Прокси работает у меня на внешнем ключе / много-к-одному. Используемое сопоставление для ассоциации:

<many-to-one name="haendler" column="VERK_HAENDLOID" lazy="proxy" />

Но проксирование не работает для меня со стороны один-на-один, используя сопоставление, подобное описанному в данном URL (constrained="true"). Хм, думаю, я открою вопрос для этого. ; -)

0 голосов
/ 21 октября 2008

При использовании аннотаций Hibernate, добавление @ManyToOne (fetch = FetchType.LAZY) в ассоциацию выполняет то, что вы хотите. Вы пытались установить fetch = "lazy", чтобы увидеть, работает ли это?

0 голосов
/ 21 октября 2008

Если вы передаете объект спящего режима из модели в представление через контроллер, не делайте этого!

Вместо этого создайте «объект снимка» для хранения значений из объекта Hibernate, который вы хотите передать в представление и отобразить.

Почему? Прокси-сервер может по-прежнему получать значения, когда он находится в контроллере ... но когда вы передаете прокси / объект в представление, он больше не может получить значения, потому что транзакция уже завершилась. И именно поэтому я предложил то, что у меня есть выше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...