我是jpa / boot的新手。我在Spring启动应用程序中使用JPA / Hibernate创建了Student
和StudentCourse
之间的一对多关系。
数据库表是student和student_course。
当我运行SchoolApplication.java
时,它失败并显示错误,'表或视图不存在'。
这是一个有效的错误,因为我没有创建表student_course_list
,只想在student
和student_course
表中插入数据。
请问您为什么hibernate正在寻找这个附加表以及如何解决此问题?
日志
Hibernate:
insert
into
student_course_list
(student, course_list)
values
(?, ?)
Caused by: org.springframework.dao.InvalidDataAccessResourceUsageException: could not execute statement; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not execute statement
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:242) ~[spring-orm-4.2.6.RELEASE.jar:4.2.6.RELEASE]
SchoolApplication.java
package com.school;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.transaction.annotation.Transactional;
import com.school.domain.Student;
import com.school.domain.StudentCourse;
import com.school.service.StudentServiceInterface;
@EntityScan(basePackages={"com.school.domain"})
@SpringBootApplication
public class SchoolApplication implements CommandLineRunner {
@Autowired
protected StudentServiceInterface studentService;
public static void main(String[] args) {
SpringApplication.run(SchoolApplication.class, args);
}
@Override
@Transactional
public void run(String... strings) throws Exception {
StudentCourse sc1 = new StudentCourse();
sc1.setCourseId(new Long(1));
sc1.setEndDate(null);
StudentCourse sc2 = new StudentCourse();
sc2.setCourseId(new Long(2));
sc2.setEndDate(null);
//Course List
List<StudentCourse> studentCourse = new ArrayList();
studentCourse.add(sc1);
studentCourse.add(sc2);
Student student = new Student();
student.setFirstName("test first");
student.setLastName("test last");
student.setCourseList(studentCourse);
studentService.saveStudent(student);
}
}
学生
@Entity
@Table(name="student")
public class Student {
@Id
@Column(name="student_id")
@GeneratedValue(strategy=GenerationType.AUTO, generator="student_seq_gen")
@SequenceGenerator(name="student_seq_gen", sequenceName="SEQ_STUDENT")
private Long studentId;
@OneToMany( targetEntity=StudentCourse.class, cascade = {CascadeType.ALL} )
private List<StudentCourse> courseList;
@Column(name="first_name")
private String firstName;
@Column(name="last_name")
private String lastName;
@Column(name="gender")
private char gender;
@Column(name="date_of_birth")
private Date dateOfBirth;
@Column(name="email")
private String email;
@Column(name="city")
private String city;
// getter and setters
.....
.....
StudentCourse
@Entity
@Table(name="student_course")
public class StudentCourse {
@Id
@Column(name="student_course_id")
@GeneratedValue(strategy=GenerationType.AUTO, generator="student_course_seq_gen")
@SequenceGenerator(name="student_course_seq_gen", sequenceName="SEQ_STUDENT_COURSE")
private Long studentCourseId;
@Column(name="student_id")
private Long studentId;
@Column(name="course_id")
private Long courseId;
@Column(name="end_date")
private Date endDate;
// getter and setters
.....
.....
更新:
StudentCourse.java:
@Entity
@Table(name="student_course")
public class StudentCourse {
@Id
@Column(name="student_course_id")
@GeneratedValue(strategy=GenerationType.AUTO, generator="student_course_seq_gen")
@SequenceGenerator(name="student_course_seq_gen", sequenceName="SEQ_STUDENT_COURSE")
private Long studentCourseId;
@JoinColumn(name="student_id", nullable = false, updatable = false, insertable = true)
@ManyToOne
private Student student;
@Column(name="course_id")
private Long courseId;
@Column(name="end_date")
private Date endDate;
答案 0 :(得分:0)
您没有告诉您的应用程序扫描实体。在您的主类上添加@EntityScan
注释。 e.g。
@SpringBootApplication
@EntityScan(basePackages={"com.example.model", "com.example.student.model"})
public class SchoolApplication implements CommandLineRunner {
...
}
BTW,@ComponentScan
是多余的,@SpringBootApplication
就足够了。如果您要查看SpringBootApplication
课程,那么您会看到@ComponentScan
。
答案 1 :(得分:0)
您没有为您的关系定义JoinColumn
(或JoinTable
ManyToMany
)。 Hibernate正在尝试创建一个表student.courseList关系属性。
按如下方式更改您的学生课程:
// You shouldn't need targetEntity, as your collection has the TargetEntity.
// this parameter is only needed if the Generic type is not present
// (e.g. private List courseList)
@OneToMany( cascade = {CascadeType.ALL}, mappedBy = "student" )
private List<StudentCourse> courseList;
按如下方式更改您的StudentCourse课程:
// Replace studentId with a Relationship
@JoinColumn(name="student_id")
@ManyToOne
private Student student;
这将告诉Hibernate学生关系 - &gt; StudentCourse由Student拥有,并由student_course表中的student_id列映射。