2016-07-14 74 views
1

我是jpa/boot的新手。我在Spring引導應用程序中使用JPA/Hibernate創建了StudentStudentCourse之間的一對多關係。JPA/Hibernate在彈簧引導應用程序中插入到非現有表中

數據庫表是student和student_course。

當我運行SchoolApplication.java,它的失敗與錯誤,'表或視圖不存在'。

這是一個有效的錯誤,因爲我還沒有創建表,student_course_list並且只想在studentstudent_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 
    ..... 
    ..... 

UPDATE:

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

您的實體沒有被應用程序掃描。你在使用Spring Data JPA存儲庫嗎? –

+0

@Rae,我使用JPA的依賴,----------- \t \t \t org.springframework.boot \t \t \t 彈簧引導起動數據JPA \t \t ---------應我使用------------ org.springframework.data 彈簧數據JPA 1.10.2.RELEASE -------改爲? – Muhammad

+0

你還沒有告訴hibernate如何保持關係,所以它假設它需要一個額外的表。你只在你的「學生課程」中擁有「long studentId」,對於「長途課程」則只有「long studentId」。這些應該是'Student'和'Course'對象,然後你可以在'@ OneToMany'上添加'mappedBy ='student'。 –

回答

0

您沒有爲您的關係定義JoinColumn(或JoinTableManyToMany)。 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,對於學生的關係 - > StudentCourse由學生擁有和映射通過student_course表中的student_id列。

+0

其工作,但不填充student_course表中的student_id。 – Muhammad

+0

您是否在「StudentCourse」中設置了「Student」?您能提供一個您正在做和看到的內容的例子嗎? – JudgingNotJudging

+0

是的,我已經提出了建議的更改。還添加了一些附加屬性(nullable = false,updatable = false,insertable = true),請參閱更新的StudentCourse.java。它將數據插入student和student_course表,但student_id(外鍵)未插入。 – Muhammad

0

你不告訴你的應用程序來掃描的實體。在你的主課上添加@EntityScan註釋。例如

@SpringBootApplication 
@EntityScan(basePackages={"com.example.model", "com.example.student.model"}) 
public class SchoolApplication implements CommandLineRunner { 
    ... 
} 

順便說一句,@ComponentScan是多餘的,@SpringBootApplication就足夠了。如果你想看看SpringBootApplication課程,你會在那裏看到@ComponentScan

+0

爲什麼需要添加EntityScan?因爲他在跑步方法中有交易?或者是什麼原因? – Patrick

+0

我添加了@EntityScan,但仍然出現相同的錯誤 – Muhammad

+1

只要「@ SpringBootApplication」位於實體的父包中,並且您的依賴項列表中包含Spring JPA庫,就不需要這樣做。 – JudgingNotJudging

相關問題