Hibernate:如何确保父项的所有子实体都不被删除?

时间:2016-03-22 11:47:16

标签: java hibernate spring-data

我正在删除entities,因此会从我的数据库中删除行。

想要删除某个实体及其所有child行。但是,我想从其Parent中删除任何行。

如何实现这一目标?

KennelParent EntityDog是我要删除的实体。

请参阅下面的代码,了解我如何在狗窝实体中链接2:

@OneToMany(cascade = CascadeType.MERGE, orphanRemoval = false)
    @JoinColumn(name = "KENNEL_ID", referencedColumnName = "ID", updatable = true, insertable = true)
    private Set<Dog> dogs;

目前,当我删除dog权利时,其相关的Kennel实体 也被删除。

编辑:狗到狗舍的映射:

@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @JoinColumn(name = "KENNEL_ID")
    private kennel kennel;

2 个答案:

答案 0 :(得分:0)

根据需要将CascadeType.ALL操作从子表切换到父表。

这是一个与您几乎相似的简单解决方案,并根据您的需要进行自定义。

@Entity(name = "Kennel")
@Table(name = "Kennel")
public class Kennel {

    @Id
    @Column(name = "Kennel_Id")
    private long kennelId;

    @Column(name = "Kennel_name")   
    private String KennelName;

    //cascade = {CascadeType.REMOVE} OR orphanRemoval = true    
   @OneToMany(cascade = {CascadeType.ALL},orphanRemoval = true,fetch =  fetchType.LAZY,mappedBy="dogKennel")    
    private Set<Dog> dogSet;
    public long getKennelId() {
        return kennelId;
    }

    public void setKennelId(long kennelId) {
        this.kennelId = kennelId;
    }

    public String getKennelName() {
        return KennelName;
    }

    public void setKennelName(String kennelName) {
        KennelName = kennelName;
    }

    public Set<Dog> getDogSet() {
        return dogSet;
    }

    public void setDogSet(Set<Dog> dogSet) {
        this.dogSet = dogSet;
    }

}

@Entity(name = "Dog")
@Table(name = "Dog")
public class Dog {

    @Id
    @Column(name = "Dog_Id")
    private int dogId;

    @ManyToOne  
    @JoinColumn(name = "Dog_Kennel_Id",referencedColumnName = "Kennel_Id")
    private Kennel dogKennel;

    @Column(name = "Dog_Name")
    private String dogName;

    public int getDogId() {
        return dogId;
    }

    public void setDogId(int dogId) {
        this.dogId = dogId;
    }

    public Kennel getDogKennel() {
        return dogKennel;
    }

    public void setDogKennel(Kennel dogKennel) {
        this.dogKennel = dogKennel;
    }

    public String getDogName() {
        return dogName;
    }

    public void setDogName(String dogName) {
        this.dogName = dogName;
    }

}



//adding kennel=1 and dog=1
        Kennel ken=new Kennel();
        ken.setKennelId(1);
        ken.setKennelName("KennelExample1");        
        HashSet<Dog> myDogSet=new HashSet<Dog>();       
        Dog dog=new Dog();
        dog.setDogId(1);
        dog.setDogName("ExampleDog1");  
        dog.setDogKennel(ken);
        myDogSet.add(dog);
        ken.setDogSet(myDogSet);        
        kennelRepo.save(ken);

        //adding dog=2 under kennel=1
        Dog dog2=new Dog();
        dog2.setDogId(2);
        dog2.setDogName("ExampleDog2"); 
        Kennel dog2ken=new Kennel();
        dog2ken.setKennelId(1);     
        dog2.setDogKennel(dog2ken);
        dogRepo.save(dog2);

        //adding dog=3 under kennel=1
        Dog dog3=new Dog();
        dog3.setDogId(3);
        dog3.setDogName("ExampleDog3");
        Kennel dog3ken=new Kennel();
        dog3ken.setKennelId(1);
        dog3.setDogKennel(dog3ken);
        dogRepo.save(dog3);

        //deleting dog=3 
        dog3=new Dog();
        dog3.setDogId(3);
        dogRepo.delete(dog3);

        //deleting kennel=1 which in turn delete all dogs under
        Kennel k=kennelRepo.findByKennelId(1);
        kennelRepo.delete(k);

答案 1 :(得分:0)

  

目前,当我删除dog entitie(s)时,其相关的Kennel实体是   也被删除了。

cascade=CascadeType.ALL注释设置为ManyToOne的原因。有了这个,我们告诉ORM当我们删除(或任何其他操作)Dog时,它也应该将相同的操作传播到Kennel实体。

Remove cascade attribute in ManyToOne(cascade = CascadeType.ALL ).
  

我可以保持kennel中显示的@oneToMany关系相同吗?

您可能想要考虑的变化很少。

  • 无需在JoinColumnoneToMany方面进行ManyTone注释。
  • 考虑在mappedBy="kennel"注释中使用OneToMany属性,并在JoinColum侧删除OneToMany注释。这使得ManyToOne成为拥有者,并且在持久化kennel实体时生成的SQL也更有效。您可以通过启用show_sql来自行检查。
  • 关于cascade上的OneToMany属性是否将其设置为ALLMERGEPERSIST, MERGE取决于您要传播到的父实体上的哪些操作儿童实体。
  • 不确定您是否已实施脚手架代码/方法来添加/更新oneToMany关系。如果不是,那么实现它们是个好主意,因为这可以确保关联在两端都得到更新。如果需要,请参阅scaffolding code