ManyToMany关系Hibernate

时间:2017-02-12 10:02:36

标签: java spring postgresql hibernate

使用Hibernate和PostgreSQL作为数据库对SpringBoot应用程序进行建模。 需要帮助才能正确建立关系ManyToMany。 课堂新闻:

@Entity(name = "news")
public class News implements Serializable {
    private Long id;
    private Date date;
    private String text;
    private String author;
    private Set<HashTag> hashTags = new HashSet<HashTag>(0);
    private byte[] image;

    public News() {
    }

    public News(Date date, String text, String author, Set<HashTag> hashTags, byte[] image) {
        this.date = date;
        this.text = text;
        this.author = author;
        this.hashTags = hashTags;
        this.image = image;
    }

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "news_id")
    public Long getId() {
        return id;
    }

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

    @Temporal(TemporalType.DATE)
    @DateTimeFormat(pattern = "DD/MM/YYYY")
    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    @Lob
    @Type(type = "org.hibernate.type.TextType")
    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinTable(name = "news_hashTag",
            joinColumns = @JoinColumn(name = "news_id"),
            inverseJoinColumns = @JoinColumn(name = "hashtag_id"))
    public Set<HashTag> getHashTags() {
        return hashTags;
    }

    public void setHashTags(Set<HashTag> hashTags) {
        this.hashTags = hashTags;
    }

    @Lob
    public byte[] getImage() {
        return image;
    }

    public void setImage(byte[] image) {
        this.image = image;
    }

班级HashTag:

@Entity(name = "hashTag")
public class HashTag implements Serializable {
    private Long id;

    private String name;
    private String description;
    private Set<News> news = new HashSet<News>(0);

    public HashTag() {
    }

    public HashTag(String name, String description) {
        this.name = name;
        this.description = description;
    }

    @Id
    @GeneratedValue (strategy = GenerationType.IDENTITY)
    @Column(name = "hashtag_id")
    public Long getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @ManyToMany(cascade = CascadeType.ALL, mappedBy = "hashTags")
    public Set<News> getNews() {
        return news;
    }

    public void setNews(Set<News> news) {
        this.news = news;
    }

当我尝试这样保存新闻时:

Set<HashTag> hashTags = new HashSet<>();
hashTags.add(new HashTag("HashTag 1");
hashTags.add(new HashTag("HashTag 2");

News news = new News();
news.text = "Some text";
news.author = "Some author";
news.date = new Date();
news.hashTags = hashTags;

newsService.save(news);

我收到错误:

  

错误:列中的空值&#34; news_id&#34;违反非空约束

1 个答案:

答案 0 :(得分:1)

让我们看看我们有什么:

在n-m关系的拥有方面:

@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinTable(name = "news_hashTag",
        joinColumns = @JoinColumn(name = "news_id"),
        inverseJoinColumns = @JoinColumn(name = "hashtag_id"))
public Set<HashTag> getHashTags() {
    return hashTags;
}

您不提供null值的排除,因为文档指定:

  

boolean nullable()默认为true;

这对于关系表和id都是错误的。你必须:

  1. 将ID设置为nullable=false
  2. 将JoinTable的所有JoinColumns设置为nullable=false
  3. 还有另一个问题:您通过newsService.save(news);进行插入和更新,您为ID指定了一个Generator但没有生成器,这在其他提供类似nextval的数据库中是可以的在Oracle中在PostGreSQL中你真的应该使用这样的序列字段:

    @Id
    @Column(name = "hashtag_id", nullable = false)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "HashTagIDGenerator")
    @SequenceGenerator(name = "HashTagIDGenerator", sequenceName = "SEQ_HASHTAG_ID")
    

    玩得开心。