代码之家  ›  专栏  ›  技术社区  ›  Mandroid

JPA:级联类型。PERSIST与多对一

  •  1
  • Mandroid  · 技术社区  · 9 年前

    我正在使用CascadeType。PERSIST与多对一

    @ManyToOne(cascade=CascadeType.PERSIST)
    @JoinColumn(name="Article")
    private Article article;
    

    持久性代码如下:

        Article article = new Article();
        article.setAuthor("Article Author");
        article.setTitle("Article Title");
        Comment comm1 = new Comment();
        comm1.setAuthor("Author1");
        comm1.setTitle("Title1");
        article.addComment(comm1);
        em.persist(comm1);
        em.getTransaction().commit();
    

    我期望使用CascadeType。字段上的PERSIST将使持久化提供者按照这样的顺序对SQL进行排序,即先持久化父实体(本文中的文章),然后持久化子实体。但相反,我得到了

    由:org.apache.openjpa.lib.jdbc引起。ReportingSQLException:无法添加或更新子行:外键约束失败

    在这种情况下,正确的做法是什么?

    文章:

    @Entity
    @NamedQuery(name="Article.findAll", query="SELECT a FROM Article a")
    public class Article implements Serializable {
    private static final long serialVersionUID = 1L;
    
    @Id
    private int id;
    
    private String author;
    
    private String title;
    
    //bi-directional many-to-one association to Comment
    @OneToMany(mappedBy="article",fetch=FetchType.LAZY,cascade=CascadeType.ALL)
    private List<Comment> comments = new ArrayList<Comment>();
    
    public List<Comment> getComments() {
        return this.comments;
    }
    
    public void setComments(List<Comment> comments) {
        this.comments = comments;
    }
    
    public Comment addComment(Comment comment) {
        getComments().add(comment);
        comment.setArticle(this);
    
        return comment;
    }
    
    ........
    

    注释:

    @Entity
    @NamedQuery(name="Comment.findAll", query="SELECT c FROM Comment c")
    public class Comment implements Serializable {
    private static final long serialVersionUID = 1L;
    
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int id;
    
    private String author;
    
    private String title;
    
    //bi-directional many-to-one association to Article
    @ManyToOne(cascade=CascadeType.PERSIST)
    @JoinColumn(name="Article")
    private Article article;
    
    ......
    

    以下工作正常:

        em.getTransaction().begin();
        Article article = new Article();
        article.setAuthor("Article Author");
        article.setTitle("Article Title");
        em.persist(article);
    
    1 回复  |  直到 9 年前
        1
  •  0
  •   Community CDub    8 年前

    实际上,实体被持久化的顺序决定了 insert 语句是生成的,所以所有的行为都如文档所示。请参见 this answer 也了解更多细节。

    Comment 首先持久化(首先显式持久化),然后 Article 将通过级联持久化。

    正确的方法是坚持 第条 首先,正如你已经指出的。