【发布时间】:2019-10-10 10:15:21
【问题描述】:
我正在尝试映射 2 个实体(课程和学生),我有 2 个 Java 类和 2 个 MySQL 表,具有ManyToMany 关系。我创建了联结表和 java 类 Enrollment(因为我想要额外的信息,例如学生注册课程的日期)。
我正在尝试在 MySQL 的这个 Enrollments 表中使用休眠功能插入数据,但我不断收到错误消息。这是我的 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);
}
}
Student 类(这个类继承自 User 父类,下面我也会附上 User Class。在数据库中也有不同的表:User,然后 Student 和 Teacher 继承了 User 父实体):
@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
最后是 Enrollment 类:
@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;
}
所以我正在尝试从数据库中读取课程和学生并将信息插入此 Enrollment 表中,但由于尝试读取课程而出现错误。这是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);
我尝试过使用注释,将它们设为多对多而不是多对一。我试图映射用户类而不是学生,但仍然没有工作。我试图在没有 Enrollment 连接类的情况下制作它,并且在没有实际类的情况下生成它,但仍然没有工作(因为我不得不一个接一个地使用 2 个 session.save() 方法,这也给了一些我无法解决的错误)。可能这是我在这里遗漏的一件小事,但我无法弄清楚,抱歉代码太长,但我真的需要快速解决它。如果你读到这里,我真的很感谢你!
所以我的问题是:我是否从这些映射和注释中遗漏了一些东西,或者我应该改变我的类的结构?
【问题讨论】: