JPA级联操作详解——级联删除(CascadeType.REMOVE)

时间:2022-08-17 05:09:25



Garage.java

package com.hibernate.jpa.bean1;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
@Entity
public class Garage {

/**
* many to one 多对一
*/
private Integer gid;
private String garagenum;
private Set<Auto> autos = new HashSet<Auto>();

@Id @GeneratedValue
public Integer getGid() {
return gid;
}
public void setGid(Integer gid) {
this.gid = gid;
}
@Column(length=20)
public String getGaragenum() {
return garagenum;
}
public void setGaragenum(String garagenum) {
this.garagenum = garagenum;
}
@OneToMany(cascade={CascadeType.PERSIST},mappedBy="garage")
public Set<Auto> getAutos() {
return autos;
}
public void setAutos(Set<Auto> autos) {
this.autos = autos;
}
public void addGarageAuto(Auto auto) {
auto.setGarage(this);
this.autos.add(auto);
}

}

Auto.java

package com.hibernate.jpa.bean1;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
@Entity
public class Auto {

/**
* one to many 一对多关联
*/
private Integer autoId;
private String autotype;
private String autonum;
private Garage garage;

@Id @GeneratedValue
public Integer getAutoId() {
return autoId;
}
public void setAutoId(Integer autoId) {
this.autoId = autoId;
}
public String getAutotype() {
return autotype;
}
public void setAutotype(String autotype) {
this.autotype = autotype;
}
public String getAutonum() {
return autonum;
}
public void setAutonum(String autonum) {
this.autonum = autonum;
}
@ManyToOne()
@JoinColumn(name="garageid")
public Garage getGarage() {
return garage;
}
public void setGarage(Garage garage) {
this.garage = garage;
}

}

持久化数据

mysql> select * from garage;
+-----+-----------+
| gid | garagenum |
+-----+-----------+
| 1 | room1 |
| 2 | room2 |
| 3 | room3 |
+-----+-----------+

mysql> select * from auto;
+--------+---------+----------+----------+
| autoId | autonum | autotype | garageid |
+--------+---------+----------+----------+
| 1 | hk2222 | car | 1 |
| 2 | bj0000 | car | 1 |
| 3 | jn1d31 | bus | 3 |
| 4 | sh3243 | car | 3 |
+--------+---------+----------+----------+

junit测试方法delete()

@Test public void delete() {
EntityManagerFactory factory = Persistence.createEntityManagerFactory("jpa-hibernate");
EntityManager em = factory.createEntityManager();
em.getTransaction().begin();
Garage garage = em.find(Garage.class, 3);
em.remove(garage);
em.getTransaction().commit();
em.close();
factory.close();
}

调用delete方法是myeclipse控制台出现异常

javax.persistence.RollbackException: Error while commiting the transaction

Caused by: java.sql.BatchUpdateException: Cannot delete or update a parent row: a foreign key constraint fails (`itcast/auto`, CONSTRAINT `FK1F51CFA8A25FB2` FOREIGN KEY (`garageid`) REFERENCES `garage` (`gid`))

发出的sql语句是:

Hibernate: select garage0_.gid as gid1_0_, garage0_.garagenum as garagenum1_0_ from Garage garage0_ where garage0_.gid=?

二)在Garage.java中添加CascadeType.REMOVE注解

@OneToMany(cascade={CascadeType.PERSIST,CascadeType.REMOVE},mappedBy="garage")
public Set<Auto> getAutos() {
return autos;
}

此时再次调用junit单元测试的delete方法

测试显示成功,发出的sql语句为

Hibernate: select garage0_.gid as gid1_0_, garage0_.garagenum as garagenum1_0_ from Garage garage0_ where garage0_.gid=?
Hibernate: select autos0_.garageid as garageid1_, autos0_.autoId as autoId1_, autos0_.autoId as autoId0_0_, autos0_.autonum as autonum0_0_, autos0_.autotype as autotype0_0_, autos0_.garageid as garageid0_0_ from Auto autos0_ where autos0_.garageid=?
Hibernate: delete from Auto where autoId=?
Hibernate: delete from Auto where autoId=?
Hibernate: delete from Garage where gid=?

此时表garage中的gid为3的字段被全部删除,同时也级联删除了与garage相关联表auto中garageid为3的字段

Sql代码 JPA级联操作详解——级联删除(CascadeType.REMOVE)JPA级联操作详解——级联删除(CascadeType.REMOVE)JPA级联操作详解——级联删除(CascadeType.REMOVE)
  1. mysql> select * from garage;
  2. +-----+-----------+
  3. | gid | garagenum |
  4. +-----+-----------+
  5. | 1 | room1 |
  6. | 2 | room2 |
  7. +-----+-----------+

Sql代码 JPA级联操作详解——级联删除(CascadeType.REMOVE)JPA级联操作详解——级联删除(CascadeType.REMOVE)JPA级联操作详解——级联删除(CascadeType.REMOVE)
  1. mysql> select * from auto;
  2. +--------+---------+----------+----------+
  3. | autoId | autonum | autotype | garageid |
  4. +--------+---------+----------+----------+
  5. | 1 | hk2222 | car | 1 |
  6. | 2 | bj0000 | car | 1 |
  7. +--------+---------+----------+----------+

怎么样,这下级联删除也明白了吧?