加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

jpa级联操作详解(转载)

(2011-01-16 21:03:36)
分类: javaee

原文链接:http://sefcertyu.javaeye.com/blog/475237

1-级联保存(CascadeType.PERSIST)

在jpa的应用中级联更新相比其他的不是很常用,但是也很有了解的必要

在这一讲的例子中我们依然以车库和汽车做实体类

Garage.java

  1. package com.hibernate.jpa.bean1;   
  2.   
  3. import java.util.HashSet;   
  4. import java.util.Set;   
  5.   
  6. import javax.persistence.CascadeType;   
  7. import javax.persistence.Column;   
  8. import javax.persistence.Entity;   
  9. import javax.persistence.FetchType;   
  10. import javax.persistence.GeneratedValue;   
  11. import javax.persistence.Id;   
  12. import javax.persistence.OneToMany;   
  13. @Entity  
  14. public class Garage {   
  15.   
  16.       
  17.     private Integer gid;   
  18.     private String garagenum;   
  19.     private Set<Auto> autos new HashSet<Auto>();   
  20.        
  21.     @Id @GeneratedValue  
  22.     public Integer getGid() {   
  23.         return gid;   
  24.     }   
  25.     public void setGid(Integer gid) {   
  26.         this.gid gid;   
  27.     }   
  28.     @Column(length=20)   
  29.     public String getGaragenum() {   
  30.         return garagenum;   
  31.     }   
  32.     public void setGaragenum(String garagenum) {   
  33.         this.garagenum garagenum;   
  34.     }   
  35.     @OneToMany(cascade={CascadeType.PERSIST},mappedBy="garage")   
  36.     public Set<Auto> getAutos() {   
  37.         return autos;   
  38.     }   
  39.         // CascadeType.PERSIST: 级联保存   
  40.     public void setAutos(Set<Auto> autos) {   
  41.         this.autos autos;   
  42.     }   
  43.     public void addGarageAuto(Auto auto) {   
  44.         auto.setGarage(this);   
  45.         this.autos.add(auto);   
  46.     }   
  47.   
  48.  
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 {

        
        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;
        }
        // CascadeType.PERSIST: 级联保存
        public void setAutos(Set<Auto> autos) {
                this.autos = autos;
        }
        public void addGarageAuto(Auto auto) {
                auto.setGarage(this);
                this.autos.add(auto);
        }

}

Auto.java

  1. package com.hibernate.jpa.bean1;   
  2.   
  3. import javax.persistence.CascadeType;   
  4. import javax.persistence.Entity;   
  5. import javax.persistence.GeneratedValue;   
  6. import javax.persistence.Id;   
  7. import javax.persistence.JoinColumn;   
  8. import javax.persistence.ManyToOne;   
  9. @Entity  
  10. public class Auto {   
  11.   
  12.       
  13.     private Integer autoId;   
  14.     private String autotype;   
  15.     private String autonum;   
  16.     private Garage garage;   
  17.   
  18.     @Id @GeneratedValue  
  19.     public Integer getAutoId() {   
  20.         return autoId;   
  21.     }   
  22.     public void setAutoId(Integer autoId) {   
  23.         this.autoId autoId;   
  24.     }   
  25.     public String getAutotype() {   
  26.         return autotype;   
  27.     }   
  28.     public void setAutotype(String autotype) {   
  29.         this.autotype autotype;   
  30.     }   
  31.     public String getAutonum() {   
  32.         return autonum;   
  33.     }   
  34.     public void setAutonum(String autonum) {   
  35.         this.autonum autonum;   
  36.     }   
  37.     @ManyToOne(cascade={CascadeType.REMOVE,CascadeType.REFRESH})   
  38.     @JoinColumn(name="garageid")   
  39.     public Garage getGarage() {   
  40.         return garage;   
  41.     }   
  42.         // CascadeType.REMOVE:级联删除  CascadeType.REFRESH:级联刷新    
  43.     public void setGarage(Garage garage) {   
  44.         this.garage garage;   
  45.     }   
  46.   
  47.  
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 {

        
        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(cascade={CascadeType.REMOVE,CascadeType.REFRESH})
        @JoinColumn(name="garageid")
        public Garage getGarage() {
                return garage;
        }
        // CascadeType.REMOVE:级联删除 ;  CascadeType.REFRESH:级联刷新 
        public void setGarage(Garage garage) {
                this.garage = garage;
        }

}

单元测试方法

  1. @Test public void update() {   
  2.     EntityManagerFactory factory Persistence.createEntityManagerFactory("jpa-hibernate");   
  3.     EntityManager em factory.createEntityManager();   
  4.     em.getTransaction().begin();   
  5.     Garage garage em.find(Garage.class1);   
  6.     garage.setGaragenum("RoomAA");   
  7.        
  8.     em.getTransaction().commit();   
  9.     em.close();   
  10.     factory.close();   
  11.  
 @Test public void update() {
                EntityManagerFactory factory = Persistence.createEntityManagerFactory("jpa-hibernate");
                EntityManager em = factory.createEntityManager();
                em.getTransaction().begin();
                Garage garage = em.find(Garage.class, 1);
                garage.setGaragenum("RoomAA");
                
                em.getTransaction().commit();
                em.close();
                factory.close();
        }

运行观察

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

 

(二)添加CascadeType.MERGE注解          //// CascadeType.MERGE 级联合并

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

将单元测试方法中的

  1. garage.setGaragenum("RoomAA");  
garage.setGaragenum("RoomAA");

改一下

  1. garage.setGaragenum("RoomBB");  
garage.setGaragenum("RoomBB");

运行update()

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

可见,这与上次发出的sql语句是一样的

2--级联删除(CascadeType.REMOVE)

aad

Garage.java

  1. package com.hibernate.jpa.bean1;   
  2.   
  3. import java.util.HashSet;   
  4. import java.util.Set;   
  5.   
  6. import javax.persistence.CascadeType;   
  7. import javax.persistence.Column;   
  8. import javax.persistence.Entity;   
  9. import javax.persistence.FetchType;   
  10. import javax.persistence.GeneratedValue;   
  11. import javax.persistence.Id;   
  12. import javax.persistence.OneToMany;   
  13. @Entity  
  14. public class Garage {   
  15.   
  16.       
  17.     private Integer gid;   
  18.     private String garagenum;   
  19.     private Set<Auto> autos new HashSet<Auto>();   
  20.        
  21.     @Id @GeneratedValue  
  22.     public Integer getGid() {   
  23.         return gid;   
  24.     }   
  25.     public void setGid(Integer gid) {   
  26.         this.gid gid;   
  27.     }   
  28.     @Column(length=20)   
  29.     public String getGaragenum() {   
  30.         return garagenum;   
  31.     }   
  32.     public void setGaragenum(String garagenum) {   
  33.         this.garagenum garagenum;   
  34.     }   
  35.     @OneToMany(cascade={CascadeType.PERSIST},mappedBy="garage")   
  36.     public Set<Auto> getAutos() {   
  37.         return autos;   
  38.     }   
  39.     public void setAutos(Set<Auto> autos) {   
  40.         this.autos autos;   
  41.     }   
  42.     public void addGarageAuto(Auto auto) {   
  43.         auto.setGarage(this);   
  44.         this.autos.add(auto);   
  45.     }   
  46.   
  47.  
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 {

        
        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

  1. package com.hibernate.jpa.bean1;   
  2.   
  3. import javax.persistence.CascadeType;   
  4. import javax.persistence.Entity;   
  5. import javax.persistence.GeneratedValue;   
  6. import javax.persistence.Id;   
  7. import javax.persistence.JoinColumn;   
  8. import javax.persistence.ManyToOne;   
  9. @Entity  
  10. public class Auto {   
  11.   
  12.       
  13.     private Integer autoId;   
  14.     private String autotype;   
  15.     private String autonum;   
  16.     private Garage garage;   
  17.   
  18.     @Id @GeneratedValue  
  19.     public Integer getAutoId() {   
  20.         return autoId;   
  21.     }   
  22.     public void setAutoId(Integer autoId) {   
  23.         this.autoId autoId;   
  24.     }   
  25.     public String getAutotype() {   
  26.         return autotype;   
  27.     }   
  28.     public void setAutotype(String autotype) {   
  29.         this.autotype autotype;   
  30.     }   
  31.     public String getAutonum() {   
  32.         return autonum;   
  33.     }   
  34.     public void setAutonum(String autonum) {   
  35.         this.autonum autonum;   
  36.     }   
  37.     @ManyToOne()   
  38.     @JoinColumn(name="garageid")   
  39.     public Garage getGarage() {   
  40.         return garage;   
  41.     }   
  42.     public void setGarage(Garage garage) {   
  43.         this.garage garage;   
  44.     }   
  45.   
  46.  
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 {

        
        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()

  1. @Test public void delete() {   
  2.     EntityManagerFactory factory Persistence.createEntityManagerFactory("jpa-hibernate");   
  3.     EntityManager em factory.createEntityManager();   
  4.     em.getTransaction().begin();   
  5.     Garage garage em.find(Garage.class3);   
  6.     em.remove(garage);   
  7.     em.getTransaction().commit();   
  8.     em.close();   
  9.     factory.close();   
  10.  
        @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语句是:

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

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

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

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

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

  1. Hibernate: select garage0_.gid as gid1_0_, garage0_.garagenum as garagenum1_0_ from Garage garage0_ where garage0_.gid=?   
  2. 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=?   
  3. Hibernate: delete from Auto where autoId=?   
  4. Hibernate: delete from Auto where autoId=?   
  5. Hibernate: delete from Garage where gid=?  
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的字段

  1. mysql> select from garage;   
  2. +-----+-----------+   
  3. gid garagenum |   
  4. +-----+-----------+   
  5.   room1     |   
  6.   room2     |   
  7. +-----+-----------+  
mysql> select * from garage;
+-----+-----------+
| gid | garagenum |
+-----+-----------+
|   1 | room1     |
|   2 | room2     |
+-----+-----------+

 

  1. mysql> select from auto;   
  2. +--------+---------+----------+----------+   
  3. autoId autonum autotype garageid |   
  4. +--------+---------+----------+----------+   
  5.      hk2222  car             |   
  6.      bj0000  car             |   
  7. +--------+---------+----------+----------+  
mysql> select * from auto;
+--------+---------+----------+----------+
| autoId | autonum | autotype | garageid |
+--------+---------+----------+----------+
|      1 | hk2222  | car      |        1 |
|      2 | bj0000  | car      |        1 |
+--------+---------+----------+----------+

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

3--级联删除(2)(CascadeType.REMOVE)

在上一讲中jpa级联操作详解2 Garage.java中有一个CascadeType.REMOVE注解,是在删除garage表中数据的时候级联删除auto表中的数据;这次我们研究在Auto中有一个CascadeType.REMOVE注解时,在删除auto表中的数据的时候能否级联删除garage表中的数据

(一)不在Auto.java添加CascadeType.REMOVE注解时

数据库中的数据如下

  1. mysql> select from auto;   
  2. +--------+---------+----------+----------+   
  3. autoId autonum autotype garageid |   
  4. +--------+---------+----------+----------+   
  5.      hk2222  car             |   
  6.      bj0000  car             |   
  7. +--------+---------+----------+----------+  
mysql> select * from auto;
+--------+---------+----------+----------+
| autoId | autonum | autotype | garageid |
+--------+---------+----------+----------+
|      1 | hk2222  | car      |        1 |
|      2 | bj0000  | car      |        1 |
+--------+---------+----------+----------+
  1. mysql> select from garage;   
  2. +-----+-----------+   
  3. gid garagenum |   
  4. +-----+-----------+   
  5.   room1     |   
  6. +-----+-----------+  
mysql> select * from garage;
+-----+-----------+
| gid | garagenum |
+-----+-----------+
|   1 | room1     |
+-----+-----------+

运行单元测试方法 delete2()

  1. @Test public void delete2() {   
  2.     EntityManagerFactory factory Persistence.createEntityManagerFactory("jpa-hibernate");   
  3.     EntityManager em factory.createEntityManager();   
  4.     em.getTransaction().begin();   
  5.     Auto auto4 em.find(Auto.class1);   
  6.     Auto auto5 em.find(Auto.class2);   
  7.     em.remove(auto4);   
  8.     em.remove(auto5);   
  9.     em.getTransaction().commit();   
  10.     em.close();   
  11.     factory.close();   
  12.  
        @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语句为:

  1. 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=?   
  2. 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=?   
  3. Hibernate: delete from Auto where autoId=?   
  4. Hibernate: delete from Auto where 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: 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字段

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

复原数据库中的数据为

  1. mysql> select from auto;   
  2. +--------+---------+----------+----------+   
  3. autoId autonum autotype garageid |   
  4. +--------+---------+----------+----------+   
  5.      hk2222  car             |   
  6.      bj0000  car             |   
  7. +--------+---------+----------+----------+  
mysql> select * from auto;
+--------+---------+----------+----------+
| autoId | autonum | autotype | garageid |
+--------+---------+----------+----------+
|      1 | hk2222  | car      |        1 |
|      2 | bj0000  | car      |        1 |
+--------+---------+----------+----------+
  1. mysql> select from garage;   
  2. +-----+-----------+   
  3. gid garagenum |   
  4. +-----+-----------+   
  5.   room1     |   
  6. +-----+-----------+  
mysql> select * from garage;
+-----+-----------+
| gid | garagenum |
+-----+-----------+
|   1 | room1     |
+-----+-----------+

重新运行delete2()方法,测试成功

打开数据库,数据显示auto表和garage表中的相关数据都被删除了

  1. mysql> select from auto;   
  2. Empty set (0.00 sec)  
mysql> select * from auto;
Empty set (0.00 sec)
  1. mysql> select from garage;   
  2. Empty set (0.00 sec)  
mysql> select * from garage;
Empty set (0.00 sec)

回看一下这次发出的sql语句为

  1. 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=?   
  2. 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=?   
  3. Hibernate: update Auto set autonum=?, autotype=?, garageid=? where autoId=?   
  4. Hibernate: delete from Auto where autoId=?   
  5. Hibernate: delete from Garage where gid=?   
  6. Hibernate: delete from Auto where 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: 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=?
 

注意http://sefcertyu.javaeye.com/images/smiles/icon_arrow.gif :如果delete2方法中改为:只删除一条记录,这样就会出错

  1. @Test public void delete2() {   
  2.     EntityManagerFactory factory Persistence.createEntityManagerFactory("jpa-hibernate");   
  3.     EntityManager em factory.createEntityManager();   
  4.     em.getTransaction().begin();   
  5.     Auto auto4 em.find(Auto.class, 1);   
  6.     em.remove(auto4);   
  7.     em.getTransaction().commit();   
  8.     em.close();   
  9.     factory.close();   
  10.  
 @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语句

  1. 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=?   
  2. Hibernate: delete from Auto where autoId=?   
  3. Hibernate: delete from Garage where gid=?  
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中的相应记录

  1. delete from Garage where gid=?  
delete from Garage where gid=?

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

4-级联更新(CascadeType.MERGE)文章分类:Java编程

在jpa的应用中级联更新相比其他的不是很常用,但是也很有了解的必要

在这一讲的例子中我们依然以车库和汽车做实体类

Garage.java

  1. package com.hibernate.jpa.bean1;   
  2.   
  3. import java.util.HashSet;   
  4. import java.util.Set;   
  5.   
  6. import javax.persistence.CascadeType;   
  7. import javax.persistence.Column;   
  8. import javax.persistence.Entity;   
  9. import javax.persistence.FetchType;   
  10. import javax.persistence.GeneratedValue;   
  11. import javax.persistence.Id;   
  12. import javax.persistence.OneToMany;   
  13. @Entity  
  14. public class Garage {   
  15.   
  16.       
  17.     private Integer gid;   
  18.     private String garagenum;   
  19.     private Set<Auto> autos new HashSet<Auto>();   
  20.        
  21.     @Id @GeneratedValue  
  22.     public Integer getGid() {   
  23.         return gid;   
  24.     }   
  25.     public void setGid(Integer gid) {   
  26.         this.gid gid;   
  27.     }   
  28.     @Column(length=20)   
  29.     public String getGaragenum() {   
  30.         return garagenum;   
  31.     }   
  32.     public void setGaragenum(String garagenum) {   
  33.         this.garagenum garagenum;   
  34.     }   
  35.     @OneToMany(cascade={CascadeType.PERSIST},mappedBy="garage")   
  36.     public Set<Auto> getAutos() {   
  37.         return autos;   
  38.     }   
  39.         // CascadeType.PERSIST: 级联保存   
  40.     public void setAutos(Set<Auto> autos) {   
  41.         this.autos autos;   
  42.     }   
  43.     public void addGarageAuto(Auto auto) {   
  44.         auto.setGarage(this);   
  45.         this.autos.add(auto);   
  46.     }   
  47.   
  48.  
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 {

        
        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;
        }
        // CascadeType.PERSIST: 级联保存
        public void setAutos(Set<Auto> autos) {
                this.autos = autos;
        }
        public void addGarageAuto(Auto auto) {
                auto.setGarage(this);
                this.autos.add(auto);
        }

}

Auto.java

  1. package com.hibernate.jpa.bean1;   
  2.   
  3. import javax.persistence.CascadeType;   
  4. import javax.persistence.Entity;   
  5. import javax.persistence.GeneratedValue;   
  6. import javax.persistence.Id;   
  7. import javax.persistence.JoinColumn;   
  8. import javax.persistence.ManyToOne;   
  9. @Entity  
  10. public class Auto {   
  11.   
  12.       
  13.     private Integer autoId;   
  14.     private String autotype;   
  15.     private String autonum;   
  16.     private Garage garage;   
  17.   
  18.     @Id @GeneratedValue  
  19.     public Integer getAutoId() {   
  20.         return autoId;   
  21.     }   
  22.     public void setAutoId(Integer autoId) {   
  23.         this.autoId autoId;   
  24.     }   
  25.     public String getAutotype() {   
  26.         return autotype;   
  27.     }   
  28.     public void setAutotype(String autotype) {   
  29.         this.autotype autotype;   
  30.     }   
  31.     public String getAutonum() {   
  32.         return autonum;   
  33.     }   
  34.     public void setAutonum(String autonum) {   
  35.         this.autonum autonum;   
  36.     }   
  37.     @ManyToOne(cascade={CascadeType.REMOVE,CascadeType.REFRESH})   
  38.     @JoinColumn(name="garageid")   
  39.     public Garage getGarage() {   
  40.         return garage;   
  41.     }   
  42.         // CascadeType.REMOVE:级联删除  CascadeType.REFRESH:级联刷新    
  43.     public void setGarage(Garage garage) {   
  44.         this.garage garage;   
  45.     }   
  46.   
  47.  
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 {

        
        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(cascade={CascadeType.REMOVE,CascadeType.REFRESH})
        @JoinColumn(name="garageid")
        public Garage getGarage() {
                return garage;
        }
        // CascadeType.REMOVE:级联删除 ;  CascadeType.REFRESH:级联刷新 
        public void setGarage(Garage garage) {
                this.garage = garage;
        }

}

单元测试方法

  1. @Test public void update() {   
  2.     EntityManagerFactory factory Persistence.createEntityManagerFactory("jpa-hibernate");   
  3.     EntityManager em factory.createEntityManager();   
  4.     em.getTransaction().begin();   
  5.     Garage garage em.find(Garage.class1);   
  6.     garage.setGaragenum("RoomAA");   
  7.        
  8.     em.getTransaction().commit();   
  9.     em.close();   
  10.     factory.close();   
  11.  
        @Test public void update() {
                EntityManagerFactory factory = Persistence.createEntityManagerFactory("jpa-hibernate");
                EntityManager em = factory.createEntityManager();
                em.getTransaction().begin();
                Garage garage = em.find(Garage.class, 1);
                garage.setGaragenum("RoomAA");
                
                em.getTransaction().commit();
                em.close();
                factory.close();
        }

运行观察

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

 

(二)添加CascadeType.MERGE注解          //// CascadeType.MERGE 级联合并

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

将单元测试方法中的

  1. garage.setGaragenum("RoomAA");  
garage.setGaragenum("RoomAA");

改一下

  1. garage.setGaragenum("RoomBB");  
garage.setGaragenum("RoomBB");

运行update()

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

可见,这与上次发出的sql语句是一样的

0

阅读 收藏 喜欢 打印举报/Report
后一篇:toplink
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有