Как Hibernate обнаруживает грязное состояние объекта? - PullRequest
56 голосов
/ 11 марта 2011

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

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

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

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

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

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

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

    А также,

  3. Достаточно ли будет hashCode() / equals() только с полем id?

Ответы [ 4 ]

93 голосов
/ 11 марта 2011

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

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

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

18 голосов
/ 21 августа 2014

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

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

Default automatic dirty checking

7 голосов
/ 07 июля 2014

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

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

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

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

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

0 голосов
/ 29 января 2017

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

...