I am deleting entities
and hence rows from my database.
I do want to delete a certain entity and all of its child
rows. However, I
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. 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.
Remove cascade attribute in ManyToOne(cascade = CascadeType.ALL ).
Can I keep the @oneToMany relationship shown in kennel the same?
Few changes you might want to consider.
JoinColumn
annotation at both oneToMany
and ManyTone
side. mappedBy="kennel"
attribute in OneToMany
annotation and remove JoinColum
annotation on OneToMany
side. This makes ManyToOne
the owning side and is also more efficient from SQLs that gets generated when you persist kennel
entity. You can check it yourself by enabling 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
relationship. 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.Switched your CascadeType.ALL operation from child table to parent table according to your need.
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);