我有两个实体“文章”和“评论”。文章与评论有OneToMany关系。
@Entity
@Table(name = "article")
public class Article implements Serializable
{
public Article()
{
}
private static final long serialVersionUID = 1L;
@Id
@Column(name = "article_id")
private int articleId;
@Column(name = "title")
private String title;
@Column(name = "category")
private String category;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "articleId", cascade = CascadeType.ALL)
private List<Comment> comments = new ArrayList<>();
}
@Entity
@Table(name = "comment")
public class Comment
{
private static final long serialVersionUID = 1L;
public Comment()
{
}
@Id
@Column(name = "comment_id")
private int commentId;
@Column(name = "author")
private String author;
@Column(name = "text")
private String text;
@JoinColumn(name = "article_id", nullable = false)
private int articleId;
}
我正在使用JPA EntityManager对Article执行CRUD操作。
我在“文章”表格中有一篇文章包含以下数据。
article_id title category
1 Java 8 in 30 days Java
我对“评论”表中的以下数据有两条评论。
comment_id author text article_id
1 ABC Java is awesome ! 1
2 XYZ Nice Article !!! 1
这是我的EntityManager代码,当包含评论的文章发布更新时会调用该代码。
public Article update(Article article)
{
return entityManager.merge(article);
}
我在这里面临的问题是,每当我使用上述方法调用从现有文章中删除评论时,评论确实不会从表中删除。我理解“merge”与“upsert”相同,但我没有在EntityManager界面中找到任何其他方法来实现注释删除以及对文章的其他更改。
答案 0 :(得分:2)
在您的代码中,@OneToMany(... cascade = CascadeType.ALL)
表示无论何时对父级进行修改(持久,删除等),它都会级联到子级。因此,如果保存了Article
,则会保存其相应的Comments
。或者,如果删除了Article
,则会删除其相应的Comments
。
在您的情况下,您想要的只是删除Comment
,与其Article
中发生的操作无关。
一种简单的方法是使用@OneToMany(... cascade = CascadeType.ALL, orphanRemoval = true)
,然后当您决定在第一个delete
上触发Comment
时,只需在其上使用Collection.remove()
:< / p>
Article article = ...;
//...
Comment targetComment = article.getComments().iterator().next();
article.getComments().remove(targetComment);
// now Hibernate considers `targetComment` as orphan and it executes an SQL DELETE for it
确保您的收藏集是唯一一个持有targetComment
引用的对象引用的收藏集,否则您的内存将会出现不一致。