Предположим, у нас есть следующие объекты JPA:
class Parent {
@Id
private Long id;
}
class Child {
@Id
private Long id;
@Column
private String name;
@ManyToOne(fetch = FetchType.LAZY)
private Parent parent;
}
Предположим, что ребенка можно однозначно идентифицировать по его имени на Родителе (комбинация обоих). Таким образом, Родитель и имя могут рассматриваться как бизнес-ключ Ребенка.
Теперь я не уверен, что наилучшим подходом было бы реализовать равные (и hashCode) в классе Child.
Ссылка на идентификатор приложения
Поскольку прокси-сервер приложения будет загружен и его идентификатор будет установлен на прокси-сервере, поэтому сам объект приложения не будет инициализирован:
public boolean equals (Object o) {
//null check, instanceof check ...
return new EqualsBuilder().append(getName(), other.getName())
.append(getParent().getId(), other.getParent().getId())
.isEquals();
}
Это поможет, но я также вижу некоторые недостатки. Во-первых (второстепенно), возможно, было бы целесообразно установить дополнительную ненулевую проверку на родительском элементе, что сделает ваши методы равными менее сложными.
Далее (менее незначительное), это потребовало бы спящего режима для доступа к свойствам, а не к полям; Итак, мне нужно было бы установить аннотации на получателях, а не на полях. Это то, с чем я могу жить лично, но привычка в текущем проекте - размещать аннотации на уровне поля.
Не использовать ссылочную сущность для оценки равенства
Хорошо, но тогда мне нужно что-то еще. Я не хочу использовать идентификатор Child (плохая практика), который оставляет мне только один вариант: использовать для этого отдельное свойство, например, UUID. Я ничего не имею против использования UUID, но, конечно, только если нет других доступных вариантов.
Мои вопросы:
- Я пропустил вариант?
- Каким, по вашему мнению, был бы рекомендуемый способ сделать это?