Я пытаюсь отобразить 2 объекта (курс и ученик), у меня есть 2 класса Java и 2 таблицы MySQL, имеющие отношение ManyToMany
. Я создал соединительную таблицу и зачисление в java-класс (так как мне нужна дополнительная информация, такая как дата зачисления студента на курс).
Я пытаюсь вставить данные, используя режим гибернации, в эту таблицу регистрации в MySQL, но продолжаю получать ошибки. Вот мои классы POJO:
курс:
@Entity
@Table(name = "course")
public class Course {
private int id;
@Column(name = "chapter_id")
private int chapterId;;
@Column(name = "name")
private String title;
@Column(name = "teacher_user_id")
private int teacherId;
@OneToMany(targetEntity=Enrolment.class, mappedBy="course", fetch=FetchType.LAZY)
// @JoinTable(name = "enrolment",
// joinColumns = @JoinColumn(name = "course_id"),
// inverseJoinColumns = @JoinColumn(name = "student_user_id"))
private List<Enrolment> enrolments = new ArrayList<Enrolment>();
public Course(){}
public Course(int id, int chapterId, String title, int teacherId) {
super();
this.id = id;
this.chapterId = chapterId;
this.title = title;
this.teacherId = teacherId;
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getChapterId() {
return chapterId;
}
public void setChapterId(int chapterId) {
this.chapterId = chapterId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getTeacherId() {
return teacherId;
}
public void setTeacherId(int teacherId) {
this.teacherId = teacherId;
}
@OneToMany(mappedBy = "course")
public List<Enrolment> getEnrolments() {
return enrolments;
}
public void setEnrolments(List<Enrolment> courses) {
this.enrolments = courses;
}
public void addEnrolment(Enrolment enrolment) {
this.enrolments.add(enrolment);
}
}
Класс ученика (этот класс унаследован от родительского класса пользователя, ниже я также прикреплю класс пользователя. В базе данных также есть разные таблицы: пользователь, а затем ученик и учитель, которые наследуют родительскую сущность пользователя):
@Entity
@Table(name = "student")
@PrimaryKeyJoinColumn(name = "user_id")
@OnDelete(action = OnDeleteAction.CASCADE)
public class Student extends User {
private int grade;
private List<Enrolment> enrolments = new ArrayList<Enrolment>();
public Student(){}
public Student(String fname, String lname, String email, String password, String address, String phone,
int userType, int grade, boolean isAdmin)
{
super(fname, lname, email, password, address, phone, userType, isAdmin);
this.grade=grade;
}
public int getGrade() {
return grade;
}
public void setGrade(int grade) {
this.grade = grade;
}
public void setEnrolments(List<Enrolment> courses) {
this.enrolments = courses;
}
@OneToMany(mappedBy = "student")
public List<Enrolment> getEnrolments() {
return enrolments;
}
public void addCourse(Enrolment course) {
this.enrolments.add(course);
}
public void addEnrolment(Enrolment enrolment) {
this.enrolments.add(enrolment);
}
}
Класс пользователя:
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@Table(name = "user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String firstname;
private String lastname;
private String email;
private String password;
private String address;
private String phone;
@Column(name = "user_type_id")
private int userType;
@Column(name = "is_admin")
private boolean isAdmin;
public User(String fname, String lname, String email, String password, String address, String phone,
int userType, boolean isAdmin) {
//super();
this.firstname = fname;
this.lastname = lname;
this.email = email;
this.password = password;
this.address = address;
this.phone = phone;
this.userType = userType;
this.isAdmin = isAdmin;
}
public User() {}
//getters & setters
И, наконец, это класс Зачисления:
@Entity
@Table(name = "enrolment")
public class Enrolment {
private int id;
private Student user;
private Course course;
@Column(name = "enrolment_date")
private Date enrolmentDate;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "student_user_id")
public User getUser() {
return user;
}
public void setUser(Student user) {
this.user = user;
}
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "course_id")
public Course getCourse() {
return course;
}
public void setCourse(Course course) {
this.course = course;
}
public Date getEnrolmentDate() {
return enrolmentDate;
}
public void setEnrolmentDate(Date enrolmentDate) {
this.enrolmentDate = enrolmentDate;
}
Итак, я пытаюсь прочитать курс и учащегося из базы данных и вставить информацию в эту таблицу зачисления, но это дает ошибки, так как я пытаюсь прочитать курс. Вот метод DAO:
@SuppressWarnings("deprecation")
@Transactional
public List<Course> getCoursesOfChapter(int chapterId) {
Configuration con = new Configuration().configure("hibernate.cfg.xml").addAnnotatedClass(Course.class);
SessionFactory sf = con.buildSessionFactory();
Session session = sf.openSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("from Course where chapter_id = :chapterId");
query.setParameter("chapterId",chapterId);
// List list = query.list();
tx.commit();
return (List<Course>) query.list();
Выдает ошибку в здании фабрики сессии:
Exception in thread "main" org.hibernate.AnnotationException: Use of @OneToMany or @ManyToMany targeting an unmapped class: models.Course.enrolments[models.Enrolment]
at org.hibernate.cfg.annotations.CollectionBinder.bindManyToManySecondPass(CollectionBinder.java:1255)
at org.hibernate.cfg.annotations.CollectionBinder.bindStarToManySecondPass(CollectionBinder.java:808)
at org.hibernate.cfg.annotations.CollectionBinder$1.secondPass(CollectionBinder.java:733)
at org.hibernate.cfg.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:54)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1696)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1664)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:287)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.build(MetadataBuildingProcess.java:84)
at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:474)
at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:85)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:689)
at dao.CourseDAO.getCourse(CourseDAO.java:52)
at webapp.Main.main(Main.java:132)
Наконец, это мой звонок:
CourseDAO cdao = new CourseDAO();
Course course = cdao.getCourse(1);
Я попробовал поиграть с аннотациями, сделать их ManyToMany вместо ManyToOne. Я пытался сопоставить класс User вместо Student, но все равно не работал. Я попытался сделать это без класса соединения Enrollment и просто сгенерировать его, не имея фактического класса для него, но все еще не работал (так как мне приходилось работать с двумя методами session.save () один за другим, что также давало некоторые ошибка, которую я не мог решить). Возможно, это небольшая вещь, которую я здесь упускаю, но я просто не могу понять это, извините за слишком длинный код, но мне действительно нужно решить это быстро. Если вы прочитали здесь, я очень благодарен вам!
Итак, мой вопрос: я что-то упускаю из этих отображений и аннотаций или мне следует изменить структуру моих классов?