Реализация equals / hashCode с использованием ссылочной сущности ManyToOne - PullRequest
4 голосов
/ 21 апреля 2011

Предположим, у нас есть следующие объекты 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, но, конечно, только если нет других доступных вариантов.

Мои вопросы:

  1. Я пропустил вариант?
  2. Каким, по вашему мнению, был бы рекомендуемый способ сделать это?

Ответы [ 2 ]

3 голосов
/ 21 апреля 2011

Другой возможностью было бы добавить другое поле, содержащее внешний ключ, к родительскому элементу, который затем можно использовать в методах equals и hashCode, не выбирая ссылочную сущность:

0 голосов
/ 21 апреля 2011

Если вы можете заполучить EntityManagerFactory (и если вы можете заполучить EntityManager, EntityManager.getEntityManagerFactory () - это один из способов сделать это), другой способ получить идентификатор родителя - с помощью:

emf.getPersistenceUnitUtil().getIdentifier(parent);

Тебе все равно нужна нулевая проверка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...