gpt4 book ai didi

java - 如何解决 hibernate 中的目标未映射类错误?

转载 作者:行者123 更新时间:2023-12-02 09:51:37 26 4
gpt4 key购买 nike

我正在尝试映射 2 个实体(类(class)和学生),我有 2 个 Java 类和 2 个 MySQL 表,它们具有 ManyToMany 关系。我创建了连接表和 java 类注册(因为我想要额外的信息,例如学生注册类(class)的日期)。

我正在尝试使用 hibernate 在 MySQL 的这个 Enrollments 表中插入数据,但我不断收到错误。这是我的 POJO 类:

类(class)类别:

@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类。在数据库中也有不同的表:User,然后是继承User父实体的Student和Teacher):

@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;
}

因此,我尝试从数据库中读取类(class)和学生,并将信息插入到此注册表中,但由于尝试读取类(class),它出现了错误。这是 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();

它在 session 工厂构建时抛出错误:

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 的连接类的情况下生成它,并且只是在没有实际类的情况下生成它,但仍然不起作用(因为我必须一个接一个地使用 2 个 session.save() 方法,这也给出了一些我无法解决的错误)。可能这是我在这里遗漏的一件小事,但我就是无法弄清楚,很抱歉代码太长,但我真的需要快速解决它。如果您读到这里,我真的非常感谢您!

所以我的问题是:我是否从这些映射和注释中遗漏了一些东西,或者我应该更改我的类的结构?

最佳答案

将问题简化到最低程度可以极大地帮助其他人帮助您。以下是您的学生、类(class)和注册类(class)的简单版本,可以轻松进行单元测试。类(class)和学生之间的多对多关联从 Enrollment 中分离为两个多对一关联。请注意,关联是双向的,并且侧由一侧映射。学生将持久化操作级联到注册,这反射(reflect)了学校通常的工作方式:学生注册类(class),而不是相反。

类(class).java

@Entity
public class Course {

@Id
@GeneratedValue
private Long id;

private String title;

@OneToMany(mappedBy = "course")
private List<Enrollment> enrollments;

Course() {
}

Course(String title) {
this.title = title;
this.enrollments = new ArrayList<>();
}

void add(Enrollment enrollment) {
enrollments.add(enrollment);
}

Long getId() {
return id;
}

List<Enrollment> getEnrollments() {
return enrollments;
}
}

Student.java

@Entity
public class Student {

@Id
@GeneratedValue
private Long id;

private String name;

@OneToMany(mappedBy = "student", cascade = ALL, orphanRemoval = true)
private List<Enrollment> enrollments;

Student() {
}

Student(String name) {
this.name = name;
this.enrollments = new ArrayList<>();
}

void enroll(Course course) {
enrollments.add(new Enrollment(course, this));
}
}

Enrollment.java

@Entity
public class Enrollment {

@Id
@GeneratedValue
private Long id;

@ManyToOne
private Course course;

@ManyToOne
private Student student;

Enrollment() {
}

Enrollment(Course course, Student student) {
this.course = course;
this.student = student;
course.add(this);
}
}

下面的测试用例检查实体是否正确映射和关联。您可以使用 Spring Boot 运行它。

SchoolTest.java

@RunWith(SpringRunner.class)
@SpringBootTest
@Transactional
public class SchoolTest {

@Autowired
private CourseRepository courseRepository;
@Autowired
private StudentRepository studentRepository;

@Test
public void run() {
Course course = courseRepository.save(new Course("cs_101"));

int studentCount = 3;
for (int i = 1; i <= studentCount; i++) {
Student student = new Student("student_" + i);
student.enroll(course);
studentRepository.save(student);
}

// push changes to the database and clear the existing entities
// to make the subsequent operations load from the database
entityManager.flush();
entityManager.clear();

Optional<Course> savedCourse = courseRepository.findById(course.getId());
assertTrue(savedCourse.isPresent());
assertEquals(studentCount, savedCourse.get().getEnrollments().size());
}
}

关于java - 如何解决 hibernate 中的目标未映射类错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56281983/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com