Дубликаты значений в связях ManyToOne в Spring

У меня есть связь типа ManyToOne между полями city и записью DictionaryItemCity (значение из справочника для города из нескольких полей) для структуры данных типа:

{
  "id": ...,
  "person": {
    ...
    "city":
    {
      "id": null,
      "value": "Moskow",
      "label": "Moskow"
    },
...
...
}

Привожу здесь только, код, имеющий отношение к проблеме, без указания всех полей сущностей:

@Entity
@Table(name = "candidates")
public class Candidate {
...
    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "person_id")
    private Person person;
...
}

@Entity
@Table(name = "persons")
public class Person {
...
    @ManyToOne(optional = false, cascade = CascadeType.ALL)
    @JoinColumn(name = "dictionary_item_city_id", nullable = false)
    private DictionaryItemCity city;
...
}

@Entity
@Table(name = "dictionary_item_cities")
public class DictionaryItemCity {
    @Id
    @GeneratedValue(generator = "uuid2")
    @GenericGenerator(name = "uuid2", strategy = "org.hibernate.id.UUIDGenerator")
    @Column(name = "dictionary_item_city_id")
    private UUID id;

    @Column(name = "value", nullable = false)
    private String value;

    @Column(name = "label", nullable = false)
    private String label;
...
Конструкторы, сеттеры, геттеры
... 
}

Проблема:

Всё работает, всё сохраняется, но запись с городом в таблице dictionary_item_cities дублируется, если сохранять кандидатов с одинаковыми городами.

То есть, если сохранить 10 кандидатов с городом вида:

{
      "id": null,
      "value": "Moskow",
      "label": "Moskow"
}

... то в таблице dictionary_item_cities будет 10 записей с разным ID:

"bcf17ed3-a762-4cd0-8462-5a824cd28357" "Moskow" "Moskow"
"..." "Moskow" "Moskow"
"..." "Moskow" "Moskow"
"..." "Moskow" "Moskow"
"..." "Moskow" "Moskow"
"..." "Moskow" "Moskow"
...
"..." "Moskow" "Moskow"

Я не знаю:

  1. Должно ли быть именно так? Считается ли это нормальной практикой? Как вообще сформулировать будущее данную особенность для общения с коллегами в терминологии Hibernate? Это особенность наследования сущностей в Hibernate?

  2. Как от этого избавиться? Как сделать так, чтобы при добавлении дубликата города с ID = null дубликат не добавлялся?

  3. Можно ли считать, что в данном случае это вызвано тем, что на уровне candidate-person используется связь типа OneToOne, и поэтому город является как бы "личной собственностью" пары candidate-person?

Идеальный вариант, как бы я хотел сделать:

  1. Чтобы таблица dictionary_item_cities была заполнена предварительными справочными данными с городами, с уже готовыми ID...
  2. Которые бы передавались на фронт в виде готовых объектов для подстановки в форму (в поле выбора города)...
  3. А с фронта подставлялись в JSON-объект кандидата уже в готовом виде, с ID...
  4. И, при сохранении в базу любых кандидатов города не дублировались, и не добавлялись совсем, а только в таблице person для каждой записи подставлялись бы ID городов. Сейчас они и так подставляются, но всё же города дублируются.

Я пробовал подставлять готовые города из базы вручную, через запрос вида:

{
  "id": null,
  "person": {
    "id": null,
    ...
    "city":
    {
      "id": "bcf17ed3-a762-4cd0-8462-5a824cd28357",
      "value": "Moskow",
      "label": "Moskow"
    },
...
...
}

Но это не даёт сохранить объект, в логах выдаётся ошибка:

org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist: ru.cnettcrm.entity.candidate.DictionaryItemCity; nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist: ru.cnettcrm.entity.candidate.DictionaryItemCity


Ответы (0 шт):