Существует хорошо известная проблема с реализацией equals () (и hashCode (), я буду говорить только о equals ()) для персистентного объекта с управляемым идентификатором базы данных.Новый объект не хранится в базе данных, поэтому не имеет идентификатора базы данных, поэтому его поле «id» имеет значение null (или 0, если это тип примитива).
Если равен id, то он будет считать все новыеобъекты равны, и как только он получает идентификатор, хэш-код изменяется, поэтому, если он уже был в коллекции, чувствительной к хэшу, он не будет найден.
Одно из решений - использование бизнес-ключа, но иногда все, кроме суррогатного идентификатора, является изменчивым.Другое решение состоит в том, чтобы сгенерировать (еще один, или использовать его в качестве идентификатора данных) суррогатный идентификатор при создании объекта.
Подход, который я не видел, состоит в том, чтобы использовать идентификатор в равных и сделать равными (и hashCode ()) сбой (сгенерировать IllegalStateException), когда идентификатор равен нулю.(и задокументируйте это поведение) Таким образом, он все еще не может быть в коллекциях хэшей, но не может быть случайно помещен туда.И для помещения его в коллекции, когда без идентификатора, может быть использована некоторая оболочка.Это хорошая / плохая идея?Есть ли у него скрытые проблемы?
Как указал Кан, если дочерние объекты должны быть помещены в свойство Set и сохранены вместе с их родителем, невозможность поместить объекты в Set до того, как они будут сохранены, является большой проблемой (а TreeSet не делает этого).справка, потому что он использует equals (), даже если он не использует hashCode ()).Я в основном использую список для дочерних объектов, поэтому его не нужно манифестировать, но это определенно проблема.