在JPA Spring中创建一对多关系

时间:2018-02-02 00:12:41

标签: spring jpa

我想将评论表和电影表与用户表相关联。我希望允许用户有很多评论,一部电影有很多评论。然后,我想在每部电影的详细信息页面中显示评论列表,为创建评论的用户提供删除或更新评论的选项。

我改变了我的代码,试图在评论和电影之间建立一对多的关系,但我得到了错误:

  

引起:org.h2.jdbc.JdbcSQLException:列不允许NULL   " FILM_ID&#34 ;; SQL语句:alter table film add column film_id bigint   不为空[23502-196]

这让我想到两件事:

1)设置为允许null或找出存在空字段的原因。我试图通过添加@Column(name = "film_id", nullable = true)来允许null,但它说参数是多余的。

2)电影表已经自动递增ID,所以加上@Column(name = "film_id")我复制一个ID?与错误消息一样说"添加列"它让我这么想?

我目前的尝试是:

Film.java

package com.demo.spring.domain;

import org.springframework.format.annotation.DateTimeFormat;

import javax.persistence.*;
import java.util.Date;
import java.util.List;

@Entity
public class Film {

    @Id @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "film_id", nullable = true)
    Long id;

    String title;
    String director;
    String description;
    @DateTimeFormat(pattern="yyyy-MM-dd")
    Date date;

    @OneToMany(cascade = CascadeType.ALL)
    @JoinColumn(name = "film_id", referencedColumnName = "film_id")
    List<Comment> comments;


    public List<Comment> getComments() {
        return comments;
    }

    public void setComments(List<Comment> comments) {
        this.comments = comments;
    }


    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }
//rest of getter and setters below//

Comment.java

package com.demo.spring.domain;

import javax.persistence.*;

@Entity
public class Comment {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "comment_id")
    Long id;

    String body;

    @Column(name = "film_id")
    Long filmId;

    public Long getFilmId() {
        return filmId;
    }

    public void setFilmId(Long filmId) {
        this.filmId = filmId;
    }

    public Comment(){

    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getBody() {
        return body;
    }

    public void setBody(String body) {
        this.body = body;
    }

}

更新

我改变了Film.java ..

自:

@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "film_id", referencedColumnName = "film_id")
List<Comment> comments;

要:

@OneToMany(cascade = CascadeType.ALL)
List<Comment> comments;

如果我添加Comment.java:

@OneToMany(cascade=CascadeType.ALL)

@JoinTable(name="film", joinColumns=@JoinColumn(name = "film_id_fk", referencedColumnName = "film_id"))

private Set<Comment> comment = new HashSet<Comment>();
Film film;

我明白了:

  

MappingException:外键   (FK5vk85sy54a8be115ye9ra1lyu:film_comments [film_film_id]))必须有   与引用的主键相同的列数(电影   [film_id_fk,comment_comment_id])

如果我将private Set<Comment> comment = new HashSet<Comment>();更改为List<Comment> comments = new ArrayList<Comment>();,我会:

  

列不允许NULL&#34; FILM_ID&#34 ;; SQL语句:alter table film   添加列film_id bigint not null

如果相反我添加:

@OneToMany(cascade=CascadeType.ALL)

@JoinColumn(name = "film_id_fk", referencedColumnName = "film_id")

private Set<Comment> comment = new HashSet<Comment>();
Film film;

我明白了:

  

MappingException:无法确定以下类型:   com.demo.spring.domain.Film,at table:comment,for columns:   [org.hibernate.mapping.Column(薄膜)]

如果我将private Set<Comment> comment = new HashSet<Comment>();更改为List<Comment> comments = new ArrayList<Comment>();,我会:

  

列不允许NULL&#34; FILM_ID&#34 ;; SQL语句:alter table film   添加列film_id bigint not null

1 个答案:

答案 0 :(得分:1)

主键不能为空,因此您无法使"film_id"成为可空。并且@JoinColumn注释是错误的,这是@ManyToOne方面的问题。 name参数应该是Comments表中的外键列的名称(因此它不能与主键同名)并且referencedColumnName应该是您在其他表格中引用的列的名称

@Entity
public class Film {

    @Id @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "film_id")
    Long id;

    String title;
    String director;
    String description;
    @DateTimeFormat(pattern="yyyy-MM-dd")
    Date date;

    @OneToMany(cascade = CascadeType.ALL)
    List<Comment> comments;

    //...

}

@Entity
public class Comment {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "comment_id")
    Long id;

    String body;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "film_id_fk", referencedColumnName = "film_id")
    Film film;

    //...

}