简体   繁体   English

Spring JPA - 删除所有子实体而不是一个

[英]Spring JPA - Removing all child entities instead of one

I have a Spring Boot app that uses Spring JPA which performs actions on a parent/child, OneToMany database relationship.我有一个 Spring 启动应用程序,它使用 Spring JPA 对父/子、OneToMany 数据库关系执行操作。 I have been perfoming save and get requests without issue for a while however I now have a need to remove a child entity from the child database table, however when I test my code I find it removes all child entities from the DB AND the parent entity which is not the behaviour I am looking for.一段时间以来,我一直在毫无问题地执行保存和获取请求,但是我现在需要从子数据库表中删除一个子实体,但是当我测试我的代码时,我发现它从数据库和父实体中删除了所有子实体这不是我要寻找的行为。

Below are the entity classes, Zoo is the parent, and Animal is the child.下面是实体类,Zoo 是父类,Animal 是子类。 They should have a oneToMany relation.他们应该有一个一对多的关系。

The parent entity.父实体。

import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;

import com.fasterxml.jackson.annotation.JsonManagedReference;

@Entity
@Table(name = "ZOOS")
public class Zoo {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", nullable = false, unique = true)
    private Integer id;
    
    @ManyToOne
    @JoinColumn(name="name")
    private String name;
    
    @OneToMany(mappedBy = "zoo", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @Fetch(value = FetchMode.SUBSELECT)
    @JsonManagedReference
    private List<Animal> animal;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public List<Animal> getAnimal() {
        return animal;
    }

    public void setAnimal(List<Animal> animal) {
        this.animal = animal;
    }
    
}

The child entity子实体

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import com.fasterxml.jackson.annotation.JsonBackReference;

@Entity
@Table(name = "ANIMALS")
public class Animal {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", nullable = false, unique = true)
    private Integer id;
    
    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "zooId")
    @JsonBackReference
    private Zoo zoo;
    
    @Column(name = "species", nullable = false)
    private String species;


    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Zoo getZoo() {
        return zoo;
    }

    public void setZoo(Zoo zoo) {
        this.zoo = zoo;
    }

    public String getSpecies() {
        return species;
    }

    public void setSpecies(String species) {
        this.species = species;
    }

}

The repo for the Animal (child) entity动物(子)实体的回购

import org.springframework.data.jpa.repository.JpaRepository;

import uk.co.example.api.entities.Animal;

public interface AnimalRepository extends JpaRepository<Animal, Integer> {

}

The java method being called to delete the animal entity调用java方法删除动物实体

    @Autowired
    AnimalRepository animalRepo;
    
    public void deleteAnimal(Integer animalId) {
        animalRepo.deleteById(animalId);
    }
    

The method should remove one animal from the Animal db table, however in practice it is removing ALL animals with the same zooId and the zoo from the Zoo db table.该方法应该从 Animal 数据库表中删除一只动物,但实际上它是从 Zoo 数据库表中删除具有相同 zooId 和动物园的所有动物。

I have researched and tried changing the CascadeType.ALL on the ManyToOne annotation in the Animal entity class to PERSIST and I've tried removing the cascade parameter altogether, in both cases I found I would get no errors in my app but no animal records would be removed at all.我已经研究并尝试将 Animal 实体 class 中 ManyToOne 注释上的 CascadeType.ALL 更改为 PERSIST 并且我尝试完全删除 cascade 参数,在这两种情况下我发现我的应用程序没有错误但没有动物记录会被完全删除。 The tables would be in the same state as before the method was run.这些表将与运行该方法之前位于相同的 state 中。

I have also tried using 'orphanRemoval = true' on the OneToMany annotation on the Zoo entity class however this doesn't seem to have any impact when testing.我还尝试在 Zoo 实体 class 的 OneToMany 注释上使用“orphanRemoval = true”,但这在测试时似乎没有任何影响。

@OneToMany(mappedBy = "zoo", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
    @Fetch(value = FetchMode.SUBSELECT)
    @JsonManagedReference
    private List<Animal> animal;

Any help will be appreciated.任何帮助将不胜感激。

The relationship from Animal to Zoo is wrong Animal 和 Zoo 的关系是错误的

@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "zooId")
@JsonBackReference
private Zoo zoo;

With CascateType.ALL if you delete an Animal also, the Zoo will be deleted, and this will issue to delete all animals.对于 CascateType.ALL,如果您还删除了一个 Animal,Zoo 将被删除,这将发出删除所有动物的命令。

You should remove the cascading because it in most cases doesn't make sense您应该删除级联,因为在大多数情况下它没有意义

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM