Jeff
Jeff

Reputation: 539

@NaturalId only valid on root entity (or its @MappedSuperclasses), using Natural Id in Joined, Multiple Table Inheritance

basically I cant find in google some similar problems by just pasting the root exception "@NaturalId only valid on root entity (or its @MappedSuperclasses)" in the search tab. I'm using a Joined, Multiple Table inheritance strategy to map my concrete/children Entities(Student,Employee) including their Abstract Parent (Person) to the three tables in my database, so far I never had a problem, Until I realize I need to implement a custom query for my Student Entity, using the Student's studentId. I manage to extract the underlying Hibernate-session from the Entity-manager and now I can clearly see and use the methods I need from my beloved HibernateSession, (we all know Hibernate has methods for naturalIds such as (byId, byNaturalId etc..)), and these kinds of methods are really really REALLY useful for querying entities. So I just annotate my studentId data member with @NaturalId until.. I performed some operation (save/create) and then multiple lines of exception are thrown to me. And the root cause is..

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

I will paste the codes of my entities for added information

The Parent abstract base class

Person class

@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

The Entity sub-class

Student class

@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

Questions: Is there a anything I can do to make a unique query for different student entities? because Hibernate's naturalId methods are really useful to perform operations with entities such as get or update

Is there any work-around to accomplish what I want without sacrificing my Design with the Entities and the database table? I want the studentId to act as a naturalId IF it would be possible. Any suggestions/help/comments please. Any thing will be greatly appreciated.

Upvotes: 2

Views: 930

Answers (1)

jansepke
jansepke

Reputation: 1979

No, unfortunately this is not possible. I think it's because you can make NaturalId queries only on the whole table, so it needs to be on a root Entity. But if you only want to make sure that schoolId is unique for all Students you can use @Column(name = "school_id", unique = true).

Upvotes: 2

Related Questions