I have the model below : an article can have some tags and a tag can be on some articles. So it is a many-to-many relationship with 3 tables :
When I delete a tag, I want to delete :
But I don't want to delete the articles in ARTICLE of course.
How can I do that ?
I try this, but it doesn't work :
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
for (Article article : tagToDelete.getArticles()) {
article.getTags().remove(tagToDelete);
}
session.delete(tagToDelete);
Thanks !
@Entity
@Table(name="ARTICLE")
public class Article extends AbstractAuditedEntity {
@Id
@Column(name="ID", nullable=false)
private Long id;
@ManyToMany
@JoinTable(name="ARTICLE_TAG", joinColumns=@JoinColumn(name = "ARTICLE_ID"), inverseJoinColumns=@JoinColumn(name = "TAG_ID"))
private Set<Tag> tags = new HashSet<>();
public Article() {}
/** Getters & Setters */
}
@Entity
@Table(name="TAG")
public class Tag {
@Id
@Column(name="ID", nullable=false)
private Long id;
@ManyToMany(mappedBy="tags")
private Set<Article> articles = new HashSet<>();
public Tag() {}
/** Getters & Setters */
}
Found the solution. On delete, we need to make sure not to cascade the delete to the Article, and vice-versa.
@ManyToMany(cascade={PERSIST, DETACH})
@JoinTable(name="ARTICLE_TAG",
joinColumns=@JoinColumn(name = "ARTICLE_ID"),
inverseJoinColumns=@JoinColumn(name = "TAG_ID"))
private Set<Tag> tags = new HashSet<>();
My problem was using CascadeType.All
, which by default includes CascadeType.REMOVE
, which will cascade the deletion of an article to the Tags it contains.
You can also add cascade={PERSIST, DETACH}
to your Tag entity to prevent the deletion of a Tag to delete its associated Article.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With