【问题标题】:Creating One to Many relation in JPA Spring在 JPA Spring 中创建一对多关系
【发布时间】:2018-02-02 11:49:09
【问题描述】:

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

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

原因:org.h2.jdbc.JdbcSQLException: NULL not allowed for column "FILM_ID"; SQL语句:alter table film add column film_id bigint 不为空 [23502-196]

这让我想到两件事:

1) 设置为允许 null 或找出为什么会有 null 字段。我尝试通过添加 @Column(name = "film_id", nullable = true) 来允许 null,但它说参数是多余的。

2) 电影表已经有自动递增的 ID,所以通过添加 @Column(name = "film_id") 我是在复制 ID 吗?与“添加列”的错误消息一样,它让我这么认为?

我目前的尝试是:

电影.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_cmets [film_film_id])) 必须有 与引用的主键相同的列数(电影 [film_id_fk,comment_comment_id])

如果我将private Set&lt;Comment&gt; comment = new HashSet&lt;Comment&gt;(); 更改为List&lt;Comment&gt; comments = new ArrayList&lt;Comment&gt;();,我会得到:

“FILM_ID”列不允许为 NULL; SQL语句:alter table film 添加列film_id bigint 不为空

如果我改为添加:

@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,表:注释,列: [org.hibernate.mapping.Column(film)]

如果我将private Set&lt;Comment&gt; comment = new HashSet&lt;Comment&gt;(); 更改为List&lt;Comment&gt; comments = new ArrayList&lt;Comment&gt;();,我会得到:

“FILM_ID”列不允许为 NULL; SQL语句:alter table film 添加列film_id bigint 不为空

【问题讨论】:

    标签: spring jpa


    【解决方案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;
    
        //...
    
    }
    

    【讨论】:

    • 谢谢你说得通。但是,在此更新后出现以下错误:“无法映射集合 com.demo.spring.domain.Film.cmets”和“无法找到具有逻辑名称的列:org.hibernate.mapping.Table(film) 中的comment_id”
    • 我的错误,我混淆了注释。 FK 应该在@ManyToOne 一侧
    • 清除了这些错误,但替换为:“NULL 不允许列“FILM_ID”;SQL 语句:alter table film add column film_id bigint not null”。将film_id添加到电影表似乎不正确?仍然是空问题。它与原始错误相同:(
    • 架构是否与注释匹配?尝试使用 Hibernate 重新生成它。如果还是不行,请尝试从 Comment 中删除 referencedColumnName 并在 Film 的 @OneToMany 注释中添加 mappedBy = "film"
    • 如果我这样做,我会得到:“mappedBy 引用了一个未知的目标实体属性:com.demo.spring.domain.Film.cmets 中的 com.demo.spring.domain.Comment.film”。我用我尝试过的其他代码和不同的错误消息更新了我的问题。我希望他们能帮助解决这个问题。当它引用外键时,我以为我已经接近了。
    猜你喜欢
    • 2023-01-16
    • 2017-10-28
    • 2018-04-14
    • 1970-01-01
    • 1970-01-01
    • 2019-01-24
    • 2017-08-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多