JPA, как создать новую сущность с тем же идентификатором, что и родительская сущность (JOINED Inheritance) - PullRequest
1 голос
/ 30 августа 2009

мой вопрос очень похож на Изменение типа объекта с сохранением его идентификатора , но вместо этого я использую InheritanceType.JOINED вместо Table_per_class.

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

Подводя итог, у меня есть класс Person и доктор, который расширяет Person и имеет тот же идентификатор. Мне нужно извлечь человека из базы данных и сделать его доктором, сохранив все данные из сущности человека, но создав дополнительные данные для доктора.

При попытке слияния врач генерирует новый идентификатор, который мне не подходит.

Вот что я попробовал в первую очередь

private Person getDoctor(Person person) {
            // Person already a doctor ==> OK
    if (person instanceof Doctor) {
        return person;
    }
            // Transient Person ==> //Transient Doctor OK
    if (person == null) {
        return new Doctor();
    }
            // Creates a Doctor from the person (only setting id...),
            // and merges it ==>
            fails as the id changes.
    Doctor doctor = new Doctor(person);
    return personDAO.merge(doctor);
}

sorry guys,first time here.

Here´s the code above:

    private Person getDoctor(Person person) {
    //Person already a doctor ==> OK 
       if (person instanceof Doctor) { 
            return person; 
    }


     //Transient Person ==> //Transient Doctor OK
        if (person == null) {
         return new Doctor(); 
        }
    //Creates a Doctor from the person (only setting id...), and merges it ==> fails as the id changes. 
    Doctor doctor = new Doctor(person);
    return personDAO.merge(doctor); 
    }


   @Inheritance(strategy = InheritanceType.JOINED)
   @Entity
   public class Person{
   }

   @Entity
   public class Doctor extends Person{
      public Doctor(Person person) {
        if (person != null) {
            this.setId(person.getId());
        }
    }
   }

1 Ответ

4 голосов
/ 30 августа 2009

Как и в вопросе, на который вы ссылаетесь, ответ «вы не можете сделать это с помощью Hibernate API».

Причина на самом деле совершенно ясна - Hibernate стремится сделать постоянство как можно более прозрачным и, следовательно, не может позволить вам делать вещи с постоянными объектами, которые вы не сможете сделать с обычными объектами Java. Как только вы создаете экземпляр Person (в простой Java), это всегда Person. Это никогда не будет Doctor. Лучшее, что вы можете сделать, - это создать экземпляр Doctor и скопировать в него атрибуты Person.

В отличие от простой Java, однако, с Hibernate вы можете обманывать и достигать того, что вы хотите :-), но это должно быть сделано с помощью собственного SQL. В вашем методе вам нужно:

  1. Исключить Person экземпляр из сеанса (и кэш 2-го уровня, если применимо)
  2. Вставить строку с соответствующим идентификатором (взятым из Person instance) в таблицу Doctors. Это та часть, которая должна быть выполнена как native sql, но вы можете определить ее как именованный запрос и установить вышеуказанный идентификатор в качестве параметра. Обратите внимание: если у вас есть какие-либо ограничения на свойства Doctor, вам нужно убедиться, что вставляемые вами значения удовлетворяют им.
  3. Обновить Person экземпляр - который теперь будет загружен как Doctor.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...