Это известная проблема с ORM. Здесь я обрисовываю решения, о которых знаю, и даю несколько советов.
1 Суррогатный / первичный ключ: автоматически сгенерированный
Как вы упомянули, если объект не был сохранен, это не сработает.
2 Суррогатный / первичный ключ: присвоенное значение
Вы можете решить присвоить значение PK в коде, таким образом, объект всегда имеет идентификатор и может использоваться для сравнения. См. Не позволяйте гибернации украсть вашу личность .
3 Натуральный ключ
Если у объекта есть другой естественный ключ, отличный от первичного, вы можете использовать этот. Это относится к клиентскому объекту, который имеет числовой первичный ключ и строковый номер клиента. Номер клиента идентифицирует клиента в реальном мире и является естественным ключом, который не изменится.
4 Значения объекта
Использование значений объекта для равенства возможно. Но есть и другие недостатки, вы упомянули. Это может быть проблематично, если значения изменяются и объект находится в коллекции . Например, если у вас есть Set
с двумя объектами, которые сначала отличались, но затем вы изменяете значения, пока они являются ссылочными в наборе, чтобы они стали равными. Тогда вы нарушаете договор Set
. См Hibernate равно и хэш-код .
5 Смешанный: значение + автогенерация первичных / суррогатных ключей
Если объекты для сравнения уже имеют идентификатор, используйте его. В противном случае используйте значения объекта для сравнения.
У всех есть свои плюсы и минусы. ИМХО, лучше всего 3, если это возможно с вашей моделью домена. В остальном я использовал 5, и это сработало, хотя при использовании коллекций все еще есть ловушка. Я никогда не использовал 2, но это звучит также разумное решение, если вы найдете способ генерировать PK в коде. Может быть, у других людей есть указатели для этого.