Как 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 автоматически обновляет измененное значение в таблице, не затрагивая другие поля. и в то же время объект объекта находится в грязном состоянии.