#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
в базовом классе и выберите стратегию, как должно быть отображено наследование (enumInheritanceType
) - аннотируйте класс
Base
с помощью@javax.persistence.MappedSuperclass
Также взгляните на аннотацию @javax.persistence.Transient
, которая дает вам возможность определить свойство в суперклассе или суперинтерфейсе без необходимости указывать там отображение.
Мне вообще не нравится наследование в модели данных, поскольку разработчики склонны использовать instanceof
оператор, который даст неожиданные результаты во время выполнения, если у вас нет фактического экземпляра вашего класса сущностей, а сгенерированный в режиме гибернации прокси-объект (в случае отложенной загрузки).
Комментарии:
1. Указание
javax.persistence.Inheritance
не является обязательным, по умолчаниюSINGLE_TABLE
. Я включил сюда не весь код, пожалуйста, предположите, что он правильный и работает (кроме части @Id).2. Вы имеете в виду, что я могу указать
@Transient
свой идентификатор базового класса, а затем дополнительно определить его в производных классах?