jpa级联操作详解3--级联删除(2)(CascadeType.REMOVE)

来源:互联网 发布:linux 启动时间 编辑:程序博客网 时间:2024/05/21 16:56

在上一讲中jpa级联操作详解2 Garage.java中有一个CascadeType.REMOVE注解,是在删除garage表中数据的时候级联删除auto表中的数据;这次我们研究在Auto中有一个CascadeType.REMOVE注解时,在删除auto表中的数据的时候能否级联删除garage表中的数据
(一)不在Auto.java添加CascadeType.REMOVE注解时
数据库中的数据如下
Sql代码 收藏代码

mysql> select * from auto;  +--------+---------+----------+----------+  | autoId | autonum | autotype | garageid |  +--------+---------+----------+----------+  |      1 | hk2222  | car      |        1 |  |      2 | bj0000  | car      |        1 |  +--------+---------+----------+----------+  

C#代码 收藏代码

mysql> select * from garage;  +-----+-----------+  | gid | garagenum |  +-----+-----------+  |   1 | room1     |  +-----+-----------+  

运行单元测试方法 delete2()
Java代码 收藏代码

@Test public void delete2() {      EntityManagerFactory factory = Persistence.createEntityManagerFactory("jpa-hibernate");      EntityManager em = factory.createEntityManager();      em.getTransaction().begin();      Auto auto4 = em.find(Auto.class, 1);      Auto auto5 = em.find(Auto.class, 2);      em.remove(auto4);      em.remove(auto5);      em.getTransaction().commit();      em.close();      factory.close();  }  

单元测试成功,auto中对应的两条字段被删除
发出的sql语句为:
Sql代码 收藏代码

Hibernate: select auto0_.autoId as autoId0_1_, auto0_.autonum as autonum0_1_, auto0_.autotype as autotype0_1_, auto0_.garageid as garageid0_1_, garage1_.gid as gid1_0_, garage1_.garagenum as garagenum1_0_ from Auto auto0_ left outer join Garage garage1_ on auto0_.garageid=garage1_.gid where auto0_.autoId=?  Hibernate: select auto0_.autoId as autoId0_1_, auto0_.autonum as autonum0_1_, auto0_.autotype as autotype0_1_, auto0_.garageid as garageid0_1_, garage1_.gid as gid1_0_, garage1_.garagenum as garagenum1_0_ from Auto auto0_ left outer join Garage garage1_ on auto0_.garageid=garage1_.gid where auto0_.autoId=?  Hibernate: delete from Auto where autoId=?  Hibernate: delete from Auto where autoId=?  

虽然auto中对应的garage字段被删除,但是garage字段gid=1时虽然在auto表中没有了对应的记录,但是这条数据依然存在

mysql> select * from garage;+-----+-----------+| gid | garagenum |+-----+-----------+| 1 | room1 |+-----+-----------+-----------------------------------------

(二)在Auto.java中加入CascadeType.REMOVE字段
Java代码 收藏代码

@ManyToOne(cascade={CascadeType.REMOVE})  @JoinColumn(name="garageid")  public Garage getGarage() {      return garage;  }  

复原数据库中的数据为
Sql代码 收藏代码

mysql> select * from auto;  +--------+---------+----------+----------+  | autoId | autonum | autotype | garageid |  +--------+---------+----------+----------+  |      1 | hk2222  | car      |        1 |  |      2 | bj0000  | car      |        1 |  +--------+---------+----------+----------+ 

C#代码 收藏代码

mysql> select * from garage;  +-----+-----------+  | gid | garagenum |  +-----+-----------+  |   1 | room1     |  +-----+-----------+  

重新运行delete2()方法,测试成功
打开数据库,数据显示auto表和garage表中的相关数据都被删除了
Sql代码 收藏代码

mysql> select * from auto;  Empty set (0.00 sec)  

Sql代码 收藏代码

mysql> select * from garage;  Empty set (0.00 sec)  

回看一下这次发出的sql语句为
Sql代码 收藏代码

Hibernate: select auto0_.autoId as autoId0_1_, auto0_.autonum as autonum0_1_, auto0_.autotype as autotype0_1_, auto0_.garageid as garageid0_1_, garage1_.gid as gid1_0_, garage1_.garagenum as garagenum1_0_ from Auto auto0_ left outer join Garage garage1_ on auto0_.garageid=garage1_.gid where auto0_.autoId=?  Hibernate: select auto0_.autoId as autoId0_1_, auto0_.autonum as autonum0_1_, auto0_.autotype as autotype0_1_, auto0_.garageid as garageid0_1_, garage1_.gid as gid1_0_, garage1_.garagenum as garagenum1_0_ from Auto auto0_ left outer join Garage garage1_ on auto0_.garageid=garage1_.gid where auto0_.autoId=?  Hibernate: update Auto set autonum=?, autotype=?, garageid=? where autoId=?  Hibernate: delete from Auto where autoId=?  Hibernate: delete from Garage where gid=?  Hibernate: delete from Auto where autoId=?  

注意 :如果delete2方法中改为:只删除一条记录,这样就会出错
Sql代码 收藏代码

@Test public void delete2() {      EntityManagerFactory factory = Persistence.createEntityManagerFactory("jpa-hibernate");      EntityManager em = factory.createEntityManager();      em.getTransaction().begin();      Auto auto4 = em.find(Auto.class, 1);      em.remove(auto4);      em.getTransaction().commit();      em.close();      factory.close();  } 

观察发出的sql语句
Sql代码 收藏代码

Hibernate: select auto0_.autoId as autoId0_1_, auto0_.autonum as autonum0_1_, auto0_.autotype as autotype0_1_, auto0_.garageid as garageid0_1_, garage1_.gid as gid1_0_, garage1_.garagenum as garagenum1_0_ from Auto auto0_ left outer join Garage garage1_ on auto0_.garageid=garage1_.gid where auto0_.autoId=?  Hibernate: delete from Auto where autoId=?  Hibernate: delete from Garage where gid=?  

我可以发现由于数据auto中有两条记录,先输出了id为1的字段记录后,由于又要删除garage中的相应记录
Sql代码 收藏代码

delete from Garage where gid=?  

但是由于还有一个外键关联相应的garage gid=1的记录,所以删除会报错

阅读全文
0 0