How to delete a row in a join table using JPA
I have a model below: the article may contain some tags, and the tag may be in some articles. So this is a many-to-many relationship with three tables:
- Article
- ARTICLE_TAG
- TAG
When I remove a tag, I want to remove:
- tag in TAG
- all relationships between tag and tags marked in ARTICLE_TAG
But I don't want, of course, to delete articles in ARTICLE.
How can i do this?
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);
Thank!
@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 */
}
source to share
Found a solution. When deleting, we have to make sure that the cascading deletion will not touch 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 article to the tags it contains.
You can also add a cascade={PERSIST, DETACH}
Tag to your entity to prevent deleting a Tag to delete its associated Article.
source to share
I am trying to delete entries like this. It worked.
Pass id
to the API and then it will remove this every entry. Try it.
Any questions please let me know.
@Entity
@Table(name="ARTICLE")
public class Article {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "article_id")
private int id;
@ManyToMany(mappedBy="article")
private Set<Article_Tag> article_tag = new HashSet<>();
public Article() {}
/** Getters & Setters */
@Entity
@Table(name="TAG")
public class Tag {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "tag_id")
private int id;
@ManyToMany(mappedBy="tag")
private Set<Article_Tag> article_tag = new HashSet<>();
public Tag() {}
/** Getters & Setters */
@Entity
@Table(name="ARTICLE_TAG")
public class Article_Tag {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private int id;
@ManyToMany(cascade={CascadeType.PERSIST, CascadeType.DETACH})
@joinColumn(name = "article_id")
private Set<Article> articles = new HashSet<>();
@ManyToMany(cascade={CascadeType.PERSIST, CascadeType.DETACH})
@joinColumn(name = "tag_id")
private Set<Tag> tags = new HashSet<>();
public Article_Tag() {}
/** Getters & Setters */
public interface Article_TagRepository extends JpaRepository<Article_Tag, Integer>{
Article_Tag findByArticle(Article id);
Article_Tag findByTag(Tag id);
}
@RestController
@RequestMapping(value = "/")
public class Article_TagController {
@Autowired
private Article_TagRepository article_tagRepository;
@GetMapping("/delete/article/{id}")
public String DeleteArticleById(@PathVariable("id") Article id) {
Article_Tag article_tag = article_tagRepository.findByArticle(id);
Integer article_tag_id = article_tag.getId();
article_tagRepository.deleteById(article_tag_id);
return "Article Successfully Deleted !!!";
}
@GetMapping("/delete/tag/{id}")
public String DeleteTagById(@PathVariable("id") Tag id) {
Article_Tag article_tag = article_tagRepository.findByTag(id);
Integer article_tag_id = article_tag.getId();
article_tagRepository.deleteById(article_tag_id);
return "Tag Successfully Deleted !!!";
}
source to share