Hibernate:保存多重关联问题

huangapple go评论164阅读模式
英文:

Hibernate: Save multiple association issue

问题

我有三个带有关联的实体。

public class Site {
    @OneToMany
    private List<Page> pages;
}

public class Page {
    @OneToMany
    private List<Article> articles;

    @OneToMany
    private List<TopArticle> topArticles;
}

public class Article {
    @ManyToOne
    private Page page;
}

public class TopArticle {
    @ManyToOne
    @JoinColumn(name = "PageId")
    private Page page;

    @OneToOne
    @JoinColumn(name = "ArticleId")
    private Article article;
}

TopArticle 中的字段 pagearticle 有数据库限制 - NOT NULL。(需要限制

我必须保存具有所有关联的 Site

Article article = new Article();
TopArticle topArticle = new TopArticle();

Page page = new Page();
page.getArticles().add(article);
page.getTopArticles().add(topArticle);

Site site = new Site();
site.getPages().add(page);

siteDAO.save(site);

有时它会成功保存站点。
但有时会抛出错误。

com.microsoft.sqlserver.jdbc.SQLServerException: 无法将值 NULL 插入列 'ArticleId','...TopArticle';列不允许为空插入失败

似乎在保存 Page 之后,它尝试保存关联的 List

articlesList topArticles
也许,在 List
articlesList topArticles 之前保存时,它可以正常工作。
以另一种方式则会失败。

问题:

在 JPA 中保存属性顺序存在问题吗?

如何强制 Hibernate 先保存 articles,然后再保存 topArticles

还有其他解决方案吗?

谢谢

英文:

I have three entities with relations.

public class Site {
    @OneToMany
    private List&lt;Page&gt; pages;
}

public class Page {
    @OneToMany
    private List&lt;Article&gt; articles;

    @OneToMany
    private List&lt;TopArticle&gt; topArticles;
}

public class Article {
    @ManyToOne
    private Page page;
}

public class TopArticle {
    @ManyToOne
    @JoinColumn(name = &quot;PageId&quot;)
    private Page page;
    
    @OneToOne
    @JoinColumn(name = &quot;ArticleId&quot;)
    private Article article;
}

Fields page and arctile in TopArticle have database restrictions - NOT NULL. (Resctrictions are required)

I have to save Site with all associations.

    Article article = new Article();
    TopArticle topArticle = new TopArticle();

    Page page = new Page();
    page.getArticles().add(article);
    page.getTopArticles().add(topArticle);

    Site site = new Site();
    site.getPages().add(page);

    siteDAO.save(site);

Sometimes it saves site.
But sometimes it throws an error.

com.microsoft.sqlserver.jdbc.SQLServerException: Cannot insert the value NULL into column &#39;ArticleId&#39;, table &#39;...TopArticle&#39;; column does not allow nulls. INSERT fails

It seems that after Page is saved, it tries to save associations List<Article> articles and List<TopArticle> topArticles.
Perhaps, when List<Article> articles are saved before List<TopArticle> topArticles it works.
In another way it fails.

Questions:

Is an issue in saving properties order in JPA?

How can I enforce Hibernate to save articles before topArticles?

Is there any other solutions?

Thanks

答案1

得分: 2

有了双向关系,您有责任确保内存中的模型的双方都设置正确,否则您将会看到您所见到的错误。

因此,您需要调用:

article.setPage(page);

而且最好将操作封装起来,以确保内存中的模型始终保持一致:

public class Page{

    public List<Article> getArticles(){
      return Collections.unmodifiableList(articles); //force through add method
    }

    public void addArticle(Article article){
        articles.add(article);
        article.setPage(this);
    }
}
英文:

With a bi-directional relationship it is your responsibility to ensure both sides are set correctly on the in-memory model otherwise you will get the error you are seeing.

So you need to call:

article.setPage(page);

And ideally you should encapsulate the operation so the in-memory model is always consistent:

public class Page{

    public List&lt;Article&gt; getArticles(){
      return Collections.unmodifiableList(articles); //force through add method
    }

    public void addArticle(Article article){
        articles.add(article);
        article.setPage(this);
    }
}

huangapple
  • 本文由 发表于 2020年7月24日 19:09:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/63072367.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定