Сохранять случайный UUID, служащий идентификатором объекта в объекте JPA?

Мне нравится использовать класс BaseDomain для всех объектов домена JPA. В базовом классе у меня есть идентификатор объекта, хранящийся в виде строки, сгенерированный из UUID.random(). ID объекта присваивается при создании объекта. Класс сущностей также имеет первичный ключ, назначаемый базой данных при сохранении.

До этого момента я всегда сохранял идентификатор объекта на основе строки. Это добавляет дополнительный столбец в каждую таблицу, но меня это не беспокоит.

Мне было интересно - есть ли причина сохранять идентификатор объекта (сгенерированный UUID)? Или случайный UUID должен оставаться в пространстве Java?

Я всегда основываю методы hashCode() и equals() класса домена на UUID, а не на первичном ключе. Это нормально, потому что UUID остается неизменным для данного объекта на протяжении всей его жизни, как в JVM, так и в базе данных.

Если я перестану сохранять UUID, как будут выглядеть методы hashCode() и equals()? Будет ли это похоже на двухуровневое сравнение: сначала с использованием первичного ключа, если он не равен нулю, а затем с использованием идентификатора объекта, если первичный ключ равен нулю?


person user935265    schedule 07.02.2014    source источник
comment
Почему бы вам не использовать UUID в качестве первичного ключа?   -  person Leonard Brünings    schedule 07.02.2014


Ответы (1)


Правильная реализация equals и hashCode действительно является серьезной проблемой для сущностей.

Вам не нужно сохранять дополнительное значение бизнес-ключа, если у вас есть «естественный» первичный ключ, например номер социального страхования для человека. Это может быть одно значение или комбинация значений, например, комбинация имени, фамилии, даты рождения и адреса. Если у вас есть такой естественный ПК, пожалуйста, используйте его. Если у вас его нет, использование UUID — прекрасный способ его создать.

Если вы используете UUID для equals и hashCode, вы также должны сохранить его, чтобы два экземпляра одной и той же записи считались равными.

Ваши equals и hashCode должны основываться на этом бизнес-ключе, а не на идентификаторе, предоставленном БД. При использовании идентификатора, предоставленного БД, все новые объекты считаются равными. Это может привести к неожиданному поведению, особенно при работе с коллекциями.

person kostja    schedule 07.02.2014
comment
Слишком поздно отвечать, но у него есть UUID.random() в его базовом DO. Итак, как вновь созданный объект будет равен, если UUID не используется в equal() и hashCode() - person Kay; 20.09.2018
comment
Если никакая комбинация атрибутов не может быть разумно использована в качестве естественного ПК, то не может быть и речи о равенстве на уровне бизнеса. Использование временных (например, autoinc) или случайных PK для идентификации бизнес-объекта может вызвать проблемы в будущем, например. сбой БД. Не использовать такие случайные или временные атрибуты для делового равенства — это как раз то, что нужно. - person kostja; 20.09.2018