Как Hibernate обнаруживает грязное состояние объекта сущности?


использует ли он какую-то модификацию байтовых кодов для исходных классов?

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

у меня проблема с hashCode() и equals() методы для сложных объектов. Я чувствую, что было бы очень медленно вычислять хэш-код, если объект имеет члены коллекции, а циклические ссылки также являются проблемой.

если Hibernate не будет использовать hashCode()/equals() чтобы проверить грязное состояние, я думаю, я не должен использовать equals()/hashCode() для объекта сущности (не объект значения), но я также Боюсь, если тот же оператор (==) не хватает.

Итак, вопросы:

  1. как Hibernate знает, если свойство объекта изменяется?

  2. вы предлагаете переопределить hashCode()/equals() методы для сложных объектов? Что делать, если они содержат циклические рекомендации?

    и

  3. Б hashCode()/equals() С id поле будет достаточно?

4 51

4 ответа:

Hibernate использует стратегию под названием инспекции, что в основном так: когда объект загружается из базы данных снимок его хранится в памяти. При сбросе сеанса Hibernate сравнивает сохраненный снимок с текущим состоянием. Если они отличаются, объект помечается как грязный, и соответствующая команда SQL ставится в очередь. Если объект все еще является временным, то он всегда грязный.

источник: книга Hibernate в действии (приложение B: реализация ORM стратегии)

важно отметить, однако, что грязная проверка Hibernate не зависит от методов equals / hascode. Hibernate вообще не смотрит на эти методы (за исключением случаев использования java.утиль.Set, но это не связано с грязной проверкой, только с API коллекций) моментальный снимок состояния, о котором я упоминал ранее, чем-то похож на массив значений. Было бы очень плохим решением оставить такой ключевой аспект фреймворка в руках разработчиков (честно говоря, разработчики не должны заботиться о грязной проверке). Излишне говорить, что equals/hascode может быть реализован многими способами в соответствии с вашими потребностями. Я рекомендую вам прочитать цитируемую книгу, там автор обсуждает стратегии реализации equals / hascode. Очень проницательное чтение.

спящий режим по умолчанию грязный механизм проверки будет соответствовать всем сопоставленным свойствам всех присоединенных в настоящее время объектов по сравнению с их начальными значениями времени загрузки.

вы можете лучше визуализировать этот процесс на следующей диаграмме:

Default automatic dirty checking

Hibernate выполняет полевую проверку для определения загрязненности объекта.

поэтому hashCode / equals вообще не входят в картину.

на самом деле, полевая грязная проверка, выполняемая Hibernate, может быть довольно дорогостоящей с точки зрения производительности.

таким образом, он предоставляет интерфейсы, такие как стратегия или перехватчик.findDirty (), чтобы справиться с тем же.

следующий пост объясняет это более подробно (наряду с некоторыми идеями для приложений к оптимизация это полностью): http://prismoskills.appspot.com/lessons/Hibernate/Chapter_20_-_Dirty_checking.jsp

Это просто-- когда вы загружаете / получаете объект сущности по идентификатору, а затем устанавливаете его новые значения полей методом setter и закрыть сессию без вызова метода update (). затем hibernate автоматически обновит измененное значение в таблице, не затрагивая другие поля. и в то же время объект находится в состоянии "грязного".