【问题标题】:Hibernate: How to ensure that a parent is not deleted when all its child entities are?Hibernate:当所有子实体都被删除时,如何确保不删除父级?
【发布时间】:2016-03-22 11:47:16
【问题描述】:

我正在删除 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;

目前,当我删除狗实体时,其相关的犬舍实体正在也被删除。

编辑:将狗映射到犬舍:

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

【问题讨论】:

  • 你能详细说明这个问题吗?当您删除 dog 实体时,犬舍中的内容会被删除吗?最好能从数据库行的角度来解释一下,哪个表的哪一行被删除了。
  • 整个 kennel 对象和行被删除
  • 如何删除它们?
  • 你能显示从 Dog 到 Kennel 的映射吗?如果您在那里有级联,那么这就是 Kennel 被删除的原因。
  • @java123999 删除ManyToOne(cascade = CascadeType.ALL ) 中的cascade 属性。使用此当前属性,当您删除 Dog 时,它也会传播到 Kennel 实体。

标签: java hibernate spring-data


【解决方案1】:

目前,当我删除狗实体时,其相关的犬舍实体是 也被删除了。

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

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

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

您可能需要考虑一些更改。

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

【讨论】:

    【解决方案2】:

    根据需要将 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);
    

    【讨论】:

      猜你喜欢
      • 2013-06-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-20
      • 1970-01-01
      • 2013-01-31
      • 1970-01-01
      • 2015-12-02
      相关资源
      最近更新 更多