[英]Hibernate: How to ensure that a parent is not deleted when all its child entities are?
I am deleting entities
and hence rows from my database. 我要删除entities
,因此要从数据库中删除行。
I do want to delete a certain entity and all of its child
rows. 我确实要删除某个实体及其所有child
行。 However, I do not want to delete any rows from its Parent
. 但是,我不想从其Parent
删除任何行。
How can I accomplish this? 我怎样才能做到这一点?
Kennel
is the Parent Entity
and Dog
is the entity I am deleting. Kennel
是Parent Entity
, Dog
是我要删除的实体。
Please see code below to how I have linked the 2 in the Kennel Entity: 请参阅下面的代码,了解我如何在“狗窝实体”中链接2:
@OneToMany(cascade = CascadeType.MERGE, orphanRemoval = false)
@JoinColumn(name = "KENNEL_ID", referencedColumnName = "ID", updatable = true, insertable = true)
private Set<Dog> dogs;
Currently, when I delete dog entitie(s), its related Kennel entity is also being deleted. 目前,当我删除狗entitie(S),其相关养犬实体也被删除。
EDIT: Mapping of Dog to Kennel: 编辑:将狗映射到狗窝:
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "KENNEL_ID")
private kennel kennel;
Switched your CascadeType.ALL operation from child table to parent table according to your need. 根据需要将CascadeType.ALL操作从子表切换到父表。
Here is the simple solution which is almost similar yours, and customize it based on your need. 这是几乎与您相似的简单解决方案,并根据您的需要对其进行自定义。
@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);
Currently, when I delete dog entitie(s), its related Kennel entity is also being deleted. 当前,当我删除狗实体时,其相关的狗窝实体也将被删除。
The reason being you have cascade=CascadeType.ALL
set on ManyToOne
annotation. 原因是在ManyToOne
批注上设置了cascade=CascadeType.ALL
。 With this we are telling the ORM that when we delete (or any other operation) Dog
it should propagate the same operation to the Kennel
entity as well. 这样,我们告诉ORM,当我们删除(或任何其他操作) Dog
它也应该将相同的操作传播到Kennel
实体。
Remove cascade attribute in ManyToOne(cascade = CascadeType.ALL ).
Can I keep the @oneToMany relationship shown in kennel the same? 我可以保持狗舍中显示的@oneToMany关系相同吗?
Few changes you might want to consider. 您可能需要考虑的更改很少。
JoinColumn
annotation at both oneToMany
and ManyTone
side. 无需在oneToMany
和ManyTone
端都具有JoinColumn
批注。 mappedBy="kennel"
attribute in OneToMany
annotation and remove JoinColum
annotation on OneToMany
side. 考虑在OneToMany
批注中使用mappedBy="kennel"
属性,并在OneToMany
一侧删除JoinColum
批注。 This makes ManyToOne
the owning side and is also more efficient from SQLs that gets generated when you persist kennel
entity. 这使ManyToOne
成为拥有者,并且在持久化kennel
实体时生成的SQL效率也更高。 You can check it yourself by enabling show_sql
. 您可以通过启用show_sql
自己检查它。 cascade
attribute on OneToMany
whether to set it to ALL
or MERGE
or PERSIST, MERGE
depends on which operations on parent entity you want to propagate to child entity. 关于OneToMany
上的cascade
属性是将其设置为ALL
还是MERGE
或PERSIST, MERGE
取决于要传播到子实体的父实体上的哪些操作。 oneToMany
relationship. 不知道您是否已经实现了脚手架代码/方法来添加/更新oneToMany
关系。 If not, it is a good idea to implement them because that ensures the association is updated on both the ends. 如果不是,则最好实现它们,因为这样可以确保在两端都更新关联。 Refer to scaffolding code if needed. 如果需要,请参考脚手架代码 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.