I'm learning hibernate and am having trouble with what looks like a simple problem. This is a varient on, but not the same as, things I have seen in google.
I have USERS that come in two types: TEACHERs and STUDENTs. USERS share a bunch of properties and the only difference between them is that TEACHERS have a set of STUDENTS and STUDENTS have one (optional) TEACHER.
My object model has 3 classes:
Code:
The Abstract USER class:
@Entity
@Inheritance
@DiscriminatorColumn(name="USER_TYPE")
@Table(name="LLUSER")
public abstract class LLUser implements Serializable {
@Id
@GeneratedValue(generator="llUserIdSequence")
public Integer lluserId;
.... several other common fields ....
}
The Teacher class:
@Entity
@DiscriminatorValue("T")
public class Teacher extends LLUser implements Serializable {
@OneToMany
private Set<Student> students;
}
The Student class:
@Entity
@DiscriminatorValue("S")
public class Student extends LLUser implements Serializable {
@ManyToOne
public Teacher teacher;
}
It is my understanding (check me on this) that the Set<Students> is managed by hibernate and does not exist in the DB tables, so the only difference between the different types of USERS is that the STUDENT needs a reference to the TEACHER row in the same table.
This seems ideal to use the single-table-per-class-hierarchy mapping into the DB tables.
The Oracle database table (in schema LL_DB) is:
Code:
CREATE TABLE LLUser (
lluserId int not null PRIMARY KEY,
User_Type varchar2(1) not null,
... several other fields ...
teacher int ,
CONSTRAINT user_type_value_check CHECK (user_type in ('T','S'))
);
ALTER TABLE LLUser modify teacher int REFERENCES LLUser(LLUSERID);
(Note that the teacher field is a reference to another row in the same table, but this
cannot be set up that way at CREATE time because the LLUser table does not yet exist. At least in Oracle.)
The problem: this throws the following exception:
Code:
Exception while preparing the app : [PersistenceUnit: ll_db] Unable to build EntityManagerFactory
.....
Caused by: org.hibernate.HibernateException: Missing column: teacher_lluserId in LL_DB.LLUSER
at org.hibernate.mapping.Table.validateColumns(Table.java:277)
at org.hibernate.cfg.Configuration.validateSchema(Configuration.java:1174)
at org.hibernate.tool.hbm2ddl.SchemaValidator.validate(SchemaValidator.java:139)
at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:387)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1385)
at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:954)
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:883)
... 46 more
This seems to be saying that Hibernate requires BOTH an object reference (teacher) AND a special ID field for the referenced TEACHER (teacher_lluserid)!
Can anyone help explain why it is not recognizing that TEACHER is a USER and therefore just uses the lluserid field of the row referenced by the foreign key in the teacher column?
Are there other annotations that I should be using here?
Do I have to go to one of the other methods of handling abstraction in order to get this kind of relationship between the subclasses?
Thanks for your help.