0

I have an entity class named Article, and another entity named ArticleTag. These two entities are manyTomany relationship, meaning that many articles could be linked to the same tag, and that many tags could be associated with the same article.

In my Article entity, I have the following:

 @ManyToMany(cascade = {CascadeType.ALL}) @JoinTable(name = "table_articleId_tagId", joinColumns = {@JoinColumn(name ="article_id")}, inverseJoinColumns = {@JoinColumn(name = "tag_id")}) private Set<ArticleTag> tags = new HashSet<ArticleTag>(); 

In my ArticleTag entity, I have this:

 @ManyToMany(mappedBy = "tags") private Set<Article> articleSet = new HashSet<Article>(); 

When my controller is called to delete an article, I use a method in my ArticleDao class that is essentially doing this:

Transaction tx = session.beginTransaction(); session.delete(article); tx.commit(); 

However, my article can't be deleted. I am not sure what causes this failure. I am wondering if I should use the Eager Fetch to delete the tags first. But this does not sound right to me, because the same tag could be linked to another article. So what's the right way of deleting article without deleting its associated tags that are still associated with another article?

Edit:

Thanks to @Vlad Mihalcea for the suggestion. With this inspiration, I started to think about reconstructing the ManyToMany relationship between Article and ArticleTag to two OneToMany relationships by creating an intermediate Entity named ArticleAndTagLink.

So my idea is to create OneToMany relationships between Article/ArticleTag with ArticleandTagLink entity. This will enable me to take advantage of the "orphanRemoval = true" annotation on either Article or ArticleTag entity. When I want to delete an Article, this annotation will help me delete the associated ArticleandTagLink object and and I will delete the tag if it does not associate any other ArticleTag objects any more. I think this may work and may probably be more efficient than iterating through tags. If it works, I'll report back tomorrow!

1

1 Answer 1

1

Hibernate delete cascade is not the same thing as SQL delete. For @ManyToMany associations the delete will propagate to the actual entities, not to the association table, and that's not what you want.

To remove the association between those two tables, prior to deleting the Article you would have too:

  1. Add delete-orphan=true to Article.tags

  2. You need to have the Article.tags collection initialized.

  3. Since you have a bidirectional association you have to remove the Article from the tags too. Iterate the Article.tags and remove the current Article from the Article.tag.articleSet (This operation could end-up in a N+1 operation, so a Batch/Subselect fetch might help).

  4. Remove all tags from the Article you want to delete.

  5. Delete the Article.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.