Как вставить несколько дочерних объектов в один и тот же родитель с наследованием JPA?

В основном у меня есть аналогичная проблема, как в этом вопросе: jpa, как создать новый объект с тем же идентификатором, что и родительский объект (JOINED Inheritance)

Но поскольку этому вопросу 9 лет, я надеюсь, что сегодня есть решение этой проблемы.

Вот моя проблема: Я использую наследование сущностей с объединенным типом наследования.

Сущности: 1 человек 2. Доктор (протягивает персону) 3. Профессор (протягивает лицо)

Вот моя актуальная проблема:

  • Когда я создаю Доктора, данные заполняются в таблицы Doctor и Person с одинаковым id, допустим id = 1 ==> Пока все хорошо

  • Когда я создаю профессора, данные заполняются в таблицы профессора и человека с одинаковым идентификатором, скажем, id = 2 ==> Пока все хорошо

  • Когда существующий доктор (id=1) теперь также становится профессором (или наоборот), я хочу, чтобы Person и Doctor сохранялись с одним и тем же id, и просто добавляю запись в таблицу Professor, тоже с id=1.

Вот код того, как я пытаюсь сделать доктора еще и профессором:

public void makeDocAlsoProf(id){

// Find existing Person
List<Person> persons = personRepo.findById(id);
Person foundPerson = !persons.isEmpty() ? persons.iterator().next() : null;

prof = new Professor(foundPerson); //This copies all parent Person fields
prof.setId(foundPerson.getId()); // Set the same id (id = 1)

prof = professorRepo.save(prof); // This gives Prof a new id (id = 3)
}

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

Человек:

  • идентификатор 1
  • идентификатор 2

Врач:

  • идентификатор 1

Профессор:

  • идентификатор 2

Вот чего я хочу добиться:

Человек:

  • идентификатор 1
  • идентификатор 2

Врач:

  • идентификатор 1

Профессор:

  • идентификатор 1
  • идентификатор 2

Вот что я получаю:

Человек:

  • идентификатор 1
  • идентификатор 2
  • идентификатор 3 (те же значения, что и 1)

Врач:

  • идентификатор 1

Профессор:

  • идентификатор 2
  • идентификатор 3

Я был бы признателен за любую помощь, даже если это невозможно, возможно, подсказку о том, как решить эту проблему, используя другой подход к модели объекта или что-то еще.

Заранее спасибо, ребята!

можно код модели?

Rafael Carrillo 01.02.2019 15:52

Таким образом, ваше сопоставление в основном таково: человек может быть и доктором, и профессором. Не могли бы вы опубликовать исходники моделей?

Angelo Immediata 01.02.2019 15:52
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
2
175
1

Ответы 1

Я думаю, что то, чего вы хотите достичь, больше похоже на образец для подражания, чем на наследство. Есть ли причина, по которой вы не назначаете роли человеку, например:

class Person {

  @ManyToMany
  private Set<Role> roles;

}

Вкус @ManyToMany, конечно, зависит от природы Role - будь то Enum или обычный объект.

Кроме того: по какой причине вы сами заботитесь об идентификаторах и не позволяете базе данных обрабатывать это, предпочтительно используя генератор последовательности? Вам лучше использовать внешние ключи вместо копирования атрибутов объекта и, возможно, идентифицировать людей по их @NaturalId, например, по адресу электронной почты и т. д.

Другие вопросы по теме