Есть ли способ переопределить унаследованную стратегию генерации?

#java #hibernate #inheritance #jpa

#java #спящий режим #наследование #jpa

Вопрос:

Я расширяю объект, который не генерирует свой идентификатор автоматически.

Я хочу «переопределить» его стратегию генерации на AUTO в моем производном классе.

Что-то вроде этого.

 @Entity
public class Base {

    @Id
    @Column(name = "id")
    public Integer getId() {
      return id;
    }

}

@Entity
public class Extender extends Base {

    @GeneratedValue(strategy = GenerationType.AUTO)
    public Integer getId() {
        return super.getId();
    }
}
  

Это то, что я получаю, когда пытаюсь это сделать:

 Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: Extender column: id (should be mapped with insert="false" update="false")
  

Я понимаю, почему это происходит, но мне нужно знать, есть ли действительный способ сделать это.

Спасибо,

Ответ №1:

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

2.4 Первичные ключи и идентификатор сущности
… Первичный ключ должен быть определен ровно один раз в иерархии сущностей.

11.1.17 Аннотация GeneratedValue
… Аннотация GeneratedValue может быть применена к свойству или полю первичного ключа объекта или отображенного суперкласса в сочетании с аннотацией Id.

Ответ №2:

Это выглядит неправильно. Если вы хотите использовать наследование, вы должны либо

  • укажите @javax.persistence.Inheritance в базовом классе и выберите стратегию, как должно быть отображено наследование (enum InheritanceType )
  • аннотируйте класс Base с помощью @javax.persistence.MappedSuperclass

Также взгляните на аннотацию @javax.persistence.Transient , которая дает вам возможность определить свойство в суперклассе или суперинтерфейсе без необходимости указывать там отображение.

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

Комментарии:

1. Указание javax.persistence.Inheritance не является обязательным, по умолчанию SINGLE_TABLE . Я включил сюда не весь код, пожалуйста, предположите, что он правильный и работает (кроме части @Id).

2. Вы имеете в виду, что я могу указать @Transient свой идентификатор базового класса, а затем дополнительно определить его в производных классах?