@NaturalId действителен только для корневого объекта (или его @MappedSuperclasses), используя Natural Id в объединенном наследовании нескольких таблиц

В основном я не могу найти в Google некоторые подобные проблемы, просто вставив корневое исключение " @NaturalId, действительный только для корневого объекта (или его @MappedSuperclasses) " на вкладке поиска. Я использую объединенную стратегию наследования нескольких таблиц, чтобы сопоставить мои конкретные / дочерние объекты (ученик, сотрудник), включая их абстрактный родительский элемент (лицо), с тремя таблицами в моей базе данных, пока у меня никогда не возникало проблем, пока я не осознаю, что необходимо реализовать пользовательский запрос для моего студенческого субъекта, используя StudentId студента. Мне удается извлечь исходный Hibernate-сеанс из Entity-менеджера, и теперь я могу ясно видеть и использовать методы, которые мне нужны из моего любимого HibernateSession (мы все знаем, что Hibernate имеет методы для NaturalIds, такие как (byId, byNaturalId и т. Д.)), и эти методы действительно ДЕЙСТВИТЕЛЬНО полезны для запроса сущностей. Поэтому я просто аннотирую свой элемент данных studentId с помощью @NaturalId до тех пор, пока... я не выполнил некоторую операцию (сохранение / создание), а затем мне выдаются несколько исключительных строк. И коренная причина это..

 org.hibernate.AnnotationException: @NaturalId only valid on root entity (or its @MappedSuperclasses)

Я буду вставлять коды моих организаций для дополнительной информации

Родительский абстрактный базовый класс

Персональный класс

@Entity
@Inheritance(strategy=InheritanceType.JOINED)
@DiscriminatorColumn(name="PERSON_TYPE")
@Table(name="PERSON")
public abstract class Person {

@Id
@GeneratedValue
@Column(name="person_ent_id", insertable = false)
private int personId;

@Column(name = "first_name")
private String firstName;

@Column(name = "last_name")
private String lastName;

@Column(name = "age")
private int age;

@Column(name = "postal_id")
private String postalId;

.. getter and setter methods declarations

Подкласс сущности

Студенческий класс

@Entity
@Table(name = "STUDENT")
@DiscriminatorValue("S")
@PrimaryKeyJoinColumn(name = "student_ent_id", referencedColumnName = "person_ent_id")
public class Student extends Person {

@Column (name = "student_ent_id", insertable=false, updatable=false)
private int studentEntId;

@NaturalId
@Column(name = "school_id")
private String schoolId;

@Column(name = "school_name")
private String shoolName;

public Student() {
    super();
}

...getter and setter methods declarations

Вопросы: Могу ли я что-нибудь сделать, чтобы сделать уникальный запрос для разных учащихся? потому что методы NaturalId Hibernate действительно полезны для выполнения операций с такими объектами, как get или update

Есть ли обходной путь для достижения того, чего я хочу, не жертвуя своим дизайном с сущностями и таблицей базы данных? Я хочу, чтобы studentId действовал как естественный, ЕСЛИ это было бы возможно. Любые предложения / помощь / комментарии, пожалуйста. Любая вещь будет с благодарностью.

1 ответ

Нет, к сожалению, это невозможно. Я думаю, это потому, что вы можете делать запросы NaturalId только для всей таблицы, поэтому он должен быть в корневом объекте. Но если вы хотите убедиться, что schoolId уникален для всех студентов, вы можете использовать @Column(name = "school_id", unique = true),