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

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

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

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

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

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

  • Как Hibernate знает, изменилось ли свойство объекта?

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

    И, также,

  • Достаточно ли hashCode()/equals() только с полем id?

Ответ 1

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

Источник: книга Hibernate in Action (приложение B: стратегии реализации ORM)

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

Ответ 2

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

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

Default automatic dirty checking

Ответ 3

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

Так что hashCode/equals вообще не входят в картину.

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

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

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

Ответ 4

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