java - 多对多关系 Hibernate

标签 java spring postgresql hibernate

使用 Hibernate 和 PostgreSQL 作为数据库对我的 SpringBoot 应用程序进行建模。 需要帮助才能正确建立多对多关系。 类(class)新闻:

@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);

我收到错误:

ERROR: null value in column "news_id" violates not-null constraint

最佳答案

让我们看看我们有什么:

在 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() default true;

这对于相关表和 ID 来说都是错误的。您必须:

  1. 将 ID 设置为 nullable=false .
  2. 将 JoinTable 的所有 JoinColumn 设置为 nullable=false .

还有一个问题:您通过 newsService.save(news); 进行插入和更新,您为 ID 指定了一个生成器,但没有生成器,这在其他提供类似 nextval 的数据库中是可以的。在甲骨文中。在 PostGreSQL 中,你确实应该使用这样的序列字段:

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

祝你玩得开心。

关于java - 多对多关系 Hibernate,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42186236/

相关文章:

java - 使用递归或任何其他解决方案替换嵌套的 FOR 循环

java - 动态创建对象的依赖注入(inject)的好处

java - 如何在ServletContextListener中使用@Autowired实例变量

Postgresql 函数无法按预期使用 INSERT INTO

ruby-on-rails - Rails PG::UndefinedColumn:错误:列 carts_parts.[:part_id, :cart_id] 不存在

java - 为什么hibernate中的Property API没有方法in(Criteria subselect)?

java - 如何将对象从 ArrayList 移动到另一个类中的 RecyclerView?

PostgreSQL:乌克兰语文本排序错误

java - Resteasy/Spring Security + Oauth 2.0 - 错误 404

Spring Security - 使用切入点的全局方法安全性不起作用