How to delete a row in join table with JPA

江枫思渺然 提交于 2020-01-13 10:12:09

问题


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 :

  • ARTICLE
  • ARTICLE_TAG
  • TAG

When I delete a tag, I want to delete :

  • the tag in TAG
  • all relations between the tag and the articles tagged in ARTICLE_TAG

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 */        
}

回答1:


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.




回答2:


I try to delete the records like that. It worked.

Pass id to API and then it deletes that each record. Try it.

Have any issues 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 !!!";
}


来源:https://stackoverflow.com/questions/43235303/how-to-delete-a-row-in-join-table-with-jpa

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!