Страницы

Поиск по вопросам

среда, 12 декабря 2018 г.

Equals(), hashCode() + ORM

Нужно ли в классах ентити всегда переопределять методы equals() и hashCode() ? И что значит не используйте ссылки на поля в методах equals() и hashCode() если классы задействованны в ORM ?


Ответ

Перегружать equals и hashCode в Entity-классах, используемых в ORM нужно по тем же причинам, по которым это нужно в других случаях:
корректное сравнение объектов, полученных из разных источников (для ORM - в разных сессиях) корректное хранение объектов в Hash* и *Set коллекциях
Нежелательность использования ссылок на поля в equals и hashCode в классах, используемых ORM, вызвано тем, что большинство ORM возвращают не непосредственно объекты вашего класса, а прокси. Прокси наследуются от ваших классов и перегружают геттеры. Во многих ORM по умолчанию стратегия получения объектов - lazy (ленивая). Это значит, что в момент, когда вы получаете объект, вы получаете пустую прокси. И только когда вы получаете значения полей через геттеры, выполняется запрос к базе, извлекающий значения полей и заполняющий ими объект. Если вы в equals или hashCode будете использовать ссылки на поля, вы можете попасть в ситуацию, когда в сравнении или вычислении хеша участвует ещё не заполненный объект. Поэтому вместо прямого доступа к полям следует использовать геттеры.
Естественно, вышесказанное относится к ORM, умеющим загружать объекты "лениво", например, к Hibernate. А вот ORM вроде MyBatis грузят объект целиком, поэтому там использование ссылок на поля в методах объекта вполне уместно.

Комментариев нет:

Отправить комментарий