首页 > 解决方案 > 如何删除多对多关系中的子实体(Spring jpa rest app)而不删除父实体?

问题描述

我在专家和标签之间有多对多的关系。我想允许用户删除专家包含的一个标签而不删除整个专家实体。现在总是我删除一个标签,所有专家也被删除。

我的 spring jpa 应用程序控制器方法通过 id 删除标签:

 @DeleteMapping("/tags/{id}")
    public ResponseEntity<Void> deleteTagById(@PathVariable Long id){
        log.debug("REST request to delete a tag by Id{} ", id);
        return tagService.deleteById(id);
    }

我的标签模型:

@Entity
@Table(name="tags")
public class Tag {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;

    @ManyToMany(mappedBy="tags", cascade = {CascadeType.ALL})
    private List<Expert> experts = new ArrayList<>();

    public Tag() {
    } //getters and setters

我的专家模型:

@Entity
@Table(name="experts")
public class Expert {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;
    private String surname;
    private String dni;
    private String address;
    private String mail;
    private String phone;
    private String linkedln;
    private String state;
    private String rating;
    private String availability;
    
    @ManyToMany(fetch = FetchType.EAGER, cascade = {CascadeType.ALL})
    @JoinTable(
            name = "experts_tags",
            joinColumns = {@JoinColumn(name="tags_id", referencedColumnName = "id")},
            inverseJoinColumns = {@JoinColumn(name="experts_id", referencedColumnName = "id")}
    )
    private List<Tag> tags = new ArrayList<>();


    public Expert() {
    } //getters and setters

到目前为止,我尝试了什么:

此方法有效地删除了标签,但也删除了专家:

public ResponseEntity<Void> deleteTag(Long id) {
        Tag tag=this.manager.find(Tag.class,id);
        this.manager.remove(tag);
        return ResponseEntity.noContent().build();

我试图避免这种方法返回 500 错误:

public ResponseEntity<Void> deleteTagById(Long id) {
        Expert expert = (Expert) manager.createQuery("SELECT  Expert from Tag u where u.id = :id");

        for(Tag tag : expert.getTags()){
            if (tag.getId() == id){
                expert.getTags().remove(tag);
                manager.persist(expert);
            }
        }
        return ResponseEntity.noContent().build();

    }
}

    }

任何人都可以帮助我吗?我很感激任何建议:) 谢谢!

标签: javaspringhibernaterest

解决方案


那是因为您定义了所有操作都应该级联到专家:

@ManyToMany(mappedBy="tags", cascade = {CascadeType.ALL})
private List<Expert> experts = new ArrayList<>();

而不是使用ALL,您应该列出您实际想要级联的内容。


推荐阅读