Использование id
объекта не является хорошей идеей, потому что временные объекты еще не имеют идентификатора (и вы все еще хотите, чтобы временный объект был потенциально равен постоянному).
Использование всех свойств (кроме идентификатора базы данных) также не очень хорошая идея, поскольку все свойства просто не являются частью идентичности.
Таким образом, предпочтительный (и правильный) способ реализации равенства - это использование бизнес-ключа , как описано в Java Persistence с Hibernate :
Реализация равенства с помощью бизнес-ключа
Чтобы получить решение, которое мы рекомендуем, вам необходимо понять понятие
бизнес ключ. Бизнес-ключ - это свойство или некоторая комбинация свойств, которые
уникален для каждого экземпляра с одинаковым идентификатором базы данных. По сути, это естественный ключ, который вы бы использовали, если бы вместо этого не использовали суррогатный первичный ключ.
В отличие от естественного первичного ключа, это не абсолютное требование, чтобы бизнес
ключ никогда не меняется - пока он меняется редко, этого достаточно.
Мы утверждаем, что, по сути, каждый класс сущностей должен иметь некоторый бизнес-ключ, даже
если он включает в себя все свойства класса (это было бы целесообразно для некоторых
неизменные классы). Бизнес-ключ - это то, что пользователь считает уникальной идентификацией конкретной записи, тогда как суррогатный ключ - это то, что приложение и
использование базы данных.
Равенство бизнес-ключей означает, что метод equals () сравнивает только те свойства, которые составляют бизнес-ключ. Это идеальное решение, которое позволяет избежать всех проблем, описанных ранее. Единственным недостатком является то, что это требует дополнительной
определить правильный бизнес-ключ в первую очередь. Это усилие требуется в любом случае;
важно идентифицировать любые уникальные ключи, если ваша база данных должна обеспечивать целостность данных посредством проверки ограничений.
Для класса User username
является отличным кандидатом в бизнес-ключ. Это никогда не ноль,
он уникален с ограничением базы данных и редко меняется, если вообще:
public class User {
...
public boolean equals(Object other) {
if (this==other) return true;
if ( !(other instanceof User) ) return false;
final User that = (User) other;
return this.username.equals( that.getUsername() );
}
public int hashCode() {
return username.hashCode();
}
}
Может быть, я что-то пропустил, но для Адреса ключом для бизнеса обычно были бы номер улицы, улица, город, почтовый индекс, страна. Я не вижу никаких проблем с этим.
На всякий случай, Equals And HashCode - еще одно интересное чтение.