jpa级联操作详解(转载)

分类: javaee |
原文链接:http://sefcertyu.javaeye.com/blog/475237
1-级联保存(CascadeType.PERSIST)
在jpa的应用中级联更新相比其他的不是很常用,但是也很有了解的必要
在这一讲的例子中我们依然以车库和汽车做实体类
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 { -
-
-
Integer gid; -
String garagenum; -
Set<Auto> newautos = HashSet<Auto>(); -
-
@GeneratedValue -
Integer getGid() { -
gid; -
} -
void setGid(Integer gid) { -
= gid; -
} -
-
String getGaragenum() { -
garagenum; -
} -
void setGaragenum(String garagenum) { -
= garagenum; -
} -
-
Set<Auto> getAutos() { -
autos; -
} -
CascadeType.PERSIST: 级联保存 -
void setAutos(Set<Auto> autos) { -
= autos; -
} -
void addGarageAuto(Auto auto) { -
auto.setGarage( -
-
} -
- }
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
- 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 { -
-
-
Integer autoId; -
String autotype; -
String autonum; -
Garage garage; -
-
@GeneratedValue -
Integer getAutoId() { -
autoId; -
} -
void setAutoId(Integer autoId) { -
= autoId; -
} -
String getAutotype() { -
autotype; -
} -
void setAutotype(String autotype) { -
= autotype; -
} -
String getAutonum() { -
autonum; -
} -
void setAutonum(String autonum) { -
= autonum; -
} -
-
-
Garage getGarage() { -
garage; -
} -
CascadeType.REMOVE:级联删除 ; CascadeType.REFRESH:级联刷新 -
void setGarage(Garage garage) { -
= garage; -
} -
- }
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; } }
单元测试方法
- @Test
public void update() { -
EntityManagerFactory factory = Persistence.createEntityManagerFacto ry( -
EntityManager em = factory.createEntityManager(); -
em.getTransaction().begin(); -
Garage garage = em.find(Garage. 1); -
garage.setGaragenum( -
-
em.getTransaction().commit(); -
em.close(); -
factory.close(); - }
@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(); }
运行观察
-
Hibernate:
select garage0_.gid asgid1_0_, asgarage0_.garagenum garagenum1_0_ fromGarage wheregarage0_ garage0_.gid=? -
Hibernate:
update Garage setgaragenum=? wheregid=?
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注解
- @OneToMany(cascade={CascadeType.PERSIST,CascadeType.MERGE},mappedBy="garage")
- public
Set<Auto> getAutos() { -
autos; - }
@OneToMany(cascade={CascadeType.PERSIST,CascadeType.MERGE},mappedBy="garage") public Set<Auto> getAutos() { return autos; }
将单元测试方法中的
- garage.setGaragenum("RoomAA");
garage.setGaragenum("RoomAA");
改一下
- garage.setGaragenum("RoomBB");
garage.setGaragenum("RoomBB");
运行update()
-
Hibernate:
select garage0_.gid asgid1_0_, asgarage0_.garagenum garagenum1_0_ fromGarage wheregarage0_ garage0_.gid=? -
Hibernate:
update Garage setgaragenum=? wheregid=?
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
- 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 { -
-
-
Integer gid; -
String garagenum; -
Set<Auto> newautos = HashSet<Auto>(); -
-
@GeneratedValue -
Integer getGid() { -
gid; -
} -
void setGid(Integer gid) { -
= gid; -
} -
-
String getGaragenum() { -
garagenum; -
} -
void setGaragenum(String garagenum) { -
= garagenum; -
} -
-
Set<Auto> getAutos() { -
autos; -
} -
void setAutos(Set<Auto> autos) { -
= autos; -
} -
void addGarageAuto(Auto auto) { -
auto.setGarage( -
-
} -
- }
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
- 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 { -
-
-
Integer autoId; -
String autotype; -
String autonum; -
Garage garage; -
-
@GeneratedValue -
Integer getAutoId() { -
autoId; -
} -
void setAutoId(Integer autoId) { -
= autoId; -
} -
String getAutotype() { -
autotype; -
} -
void setAutotype(String autotype) { -
= autotype; -
} -
String getAutonum() { -
autonum; -
} -
void setAutonum(String autonum) { -
= autonum; -
} -
-
-
Garage getGarage() { -
garage; -
} -
void setGarage(Garage garage) { -
= garage; -
} -
- }
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()
- @Test
public void delete() { -
EntityManagerFactory factory = Persistence.createEntityManagerFacto ry( -
EntityManager em = factory.createEntityManager(); -
em.getTransaction().begin(); -
Garage garage = em.find(Garage. 3); -
em.remove(garage); -
em.getTransaction().commit(); -
em.close(); -
factory.close(); - }
@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 asgarage0_.gid gid1_0_, asgarage0_.garagenum 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注解
- @OneToMany(cascade={CascadeType.PERSIST,CascadeType.REMOVE},mappedBy="garage")
- public
Set<Auto> getAutos() { -
autos; - }
@OneToMany(cascade={CascadeType.PERSIST,CascadeType.REMOVE},mappedBy="garage") public Set<Auto> getAutos() { return autos; }
此时再次调用junit单元测试的delete方法
测试显示成功,发出的sql语句为
-
Hibernate:
select garage0_.gid asgid1_0_, asgarage0_.garagenum garagenum1_0_ fromGarage wheregarage0_ garage0_.gid=? -
Hibernate:
select autos0_.garageid asgarageid1_, asautos0_.autoId autoId1_, asautos0_.autoId autoId0_0_, asautos0_.autonum autonum0_0_, asautos0_.autotype autotype0_0_, asautos0_.garageid garageid0_0_ fromAuto whereautos0_ autos0_.garageid=? -
Hibernate:
delete from Auto whereautoId=? -
Hibernate:
delete from Auto whereautoId=? -
Hibernate:
delete from Garage wheregid=?
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的字段
-
mysql>
select * fromgarage; - +-----+-----------+
-
|
gid | garagenum | - +-----+-----------+
-
|
1 | room1 | -
|
2 | room2 | - +-----+-----------+
mysql> select * from garage; +-----+-----------+ | gid | garagenum | +-----+-----------+ | 1 | room1 | | 2 | room2 | +-----+-----------+
-
mysql>
select * fromauto; - +--------+---------+----------+----------+
-
|
autoId | autonum | autotype | garageid | - +--------+---------+----------+----------+
-
|
1 | hk2222 | car | 1 | -
|
2 | bj0000 | car | 1 | - +--------+---------+----------+----------+
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注解时
数据库中的数据如下
-
mysql>
select * fromauto; - +--------+---------+----------+----------+
-
|
autoId | autonum | autotype | garageid | - +--------+---------+----------+----------+
-
|
1 | hk2222 | car | 1 | -
|
2 | bj0000 | car | 1 | - +--------+---------+----------+----------+
mysql> select * from auto; +--------+---------+----------+----------+ | autoId | autonum | autotype | garageid | +--------+---------+----------+----------+ | 1 | hk2222 | car | 1 | | 2 | bj0000 | car | 1 | +--------+---------+----------+----------+
-
mysql>
select * from garage; - +-----+-----------+
-
|
gid | garagenum | - +-----+-----------+
-
|
1 | room1 | -
+-----+-----------+
mysql> select * from garage; +-----+-----------+ | gid | garagenum | +-----+-----------+ | 1 | room1 | +-----+-----------+
运行单元测试方法 delete2()
- @Test
public void delete2() { -
EntityManagerFactory factory = Persistence.createEntityManagerFacto ry( -
EntityManager em = factory.createEntityManager(); -
em.getTransaction().begin(); -
Auto auto4 = em.find(Auto. 1); -
Auto auto5 = em.find(Auto. 2); -
em.remove(auto4); -
em.remove(auto5); -
em.getTransaction().commit(); -
em.close(); -
factory.close(); - }
@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语句为:
-
Hibernate:
select auto0_.autoId asautoId0_1_, asauto0_.autonum autonum0_1_, asauto0_.autotype autotype0_1_, asauto0_.garageid garageid0_1_, asgarage1_.gid gid1_0_, asgarage1_.garagenum garagenum1_0_ fromAuto leftauto0_ outer join Garage ongarage1_ auto0_.garageid=garage1_.gid whereauto0_.autoId=? -
Hibernate:
select auto0_.autoId asautoId0_1_, asauto0_.autonum autonum0_1_, asauto0_.autotype autotype0_1_, asauto0_.garageid garageid0_1_, asgarage1_.gid gid1_0_, asgarage1_.garagenum garagenum1_0_ fromAuto leftauto0_ outer join Garage ongarage1_ auto0_.garageid=garage1_.gid whereauto0_.autoId=? -
Hibernate:
delete from Auto whereautoId=? -
Hibernate:
delete from Auto whereautoId=?
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字段
- @ManyToOne(cascade={CascadeType.REMOVE})
- @JoinColumn(name="garageid")
- public
Garage getGarage() { -
garage; - }
@ManyToOne(cascade={CascadeType.REMOVE}) @JoinColumn(name="garageid") public Garage getGarage() { return garage; }
复原数据库中的数据为
-
mysql>
select * fromauto; - +--------+---------+----------+----------+
-
|
autoId | autonum | autotype | garageid | - +--------+---------+----------+----------+
-
|
1 | hk2222 | car | 1 | -
|
2 | bj0000 | car | 1 | - +--------+---------+----------+----------+
mysql> select * from auto; +--------+---------+----------+----------+ | autoId | autonum | autotype | garageid | +--------+---------+----------+----------+ | 1 | hk2222 | car | 1 | | 2 | bj0000 | car | 1 | +--------+---------+----------+----------+
-
mysql>
select * from garage; - +-----+-----------+
-
|
gid | garagenum | - +-----+-----------+
-
|
1 | room1 | -
+-----+-----------+
mysql> select * from garage; +-----+-----------+ | gid | garagenum | +-----+-----------+ | 1 | room1 | +-----+-----------+
重新运行delete2()方法,测试成功
打开数据库,数据显示auto表和garage表中的相关数据都被删除了
-
mysql>
select * fromauto; - Empty
set (0.00 sec)
mysql> select * from auto; Empty set (0.00 sec)
-
mysql>
select * fromgarage; - Empty
set (0.00 sec)
mysql> select * from garage; Empty set (0.00 sec)
回看一下这次发出的sql语句为
-
Hibernate:
select auto0_.autoId asautoId0_1_, asauto0_.autonum autonum0_1_, asauto0_.autotype autotype0_1_, asauto0_.garageid garageid0_1_, asgarage1_.gid gid1_0_, asgarage1_.garagenum garagenum1_0_ fromAuto leftauto0_ outer join Garage ongarage1_ auto0_.garageid=garage1_.gid whereauto0_.autoId=? -
Hibernate:
select auto0_.autoId asautoId0_1_, asauto0_.autonum autonum0_1_, asauto0_.autotype autotype0_1_, asauto0_.garageid garageid0_1_, asgarage1_.gid gid1_0_, asgarage1_.garagenum garagenum1_0_ fromAuto leftauto0_ outer join Garage ongarage1_ auto0_.garageid=garage1_.gid whereauto0_.autoId=? -
Hibernate:
update Auto setautonum=?, whereautotype=?, garageid=? autoId=? -
Hibernate:
delete from Auto whereautoId=? -
Hibernate:
delete from Garage wheregid=? -
Hibernate:
delete from Auto whereautoId=?
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方法中改为:只删除一条记录,这样就会出错
-
@Test
public void delete2() { -
EntityManagerFactory factory = Persistence.createEntityManagerFacto ry( -
EntityManager em = factory.createEntityManager(); -
em.getTransaction(). -
Auto auto4 = em.find(Auto.class, 1); -
em.remove(auto4); -
em.getTransaction(). -
em. -
factory. - }
@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(); }
-
Hibernate:
select auto0_.autoId asautoId0_1_, asauto0_.autonum autonum0_1_, asauto0_.autotype autotype0_1_, asauto0_.garageid garageid0_1_, asgarage1_.gid gid1_0_, asgarage1_.garagenum garagenum1_0_ fromAuto leftauto0_ outer join Garage ongarage1_ auto0_.garageid=garage1_.gid whereauto0_.autoId=? -
Hibernate:
delete from Auto whereautoId=? -
Hibernate:
delete from Garage wheregid=?
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=?
- delete
from Garage wheregid=?
delete from Garage where gid=?
但是由于还有一个外键关联相应的garage gid=1的记录,所以删除会报错
4-级联更新(CascadeType.MERGE)文章分类:Java编程
在jpa的应用中级联更新相比其他的不是很常用,但是也很有了解的必要
在这一讲的例子中我们依然以车库和汽车做实体类
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 { -
-
-
Integer gid; -
String garagenum; -
Set<Auto> newautos = HashSet<Auto>(); -
-
@GeneratedValue -
Integer getGid() { -
gid; -
} -
void setGid(Integer gid) { -
= gid; -
} -
-
String getGaragenum() { -
garagenum; -
} -
void setGaragenum(String garagenum) { -
= garagenum; -
} -
-
Set<Auto> getAutos() { -
autos; -
} -
CascadeType.PERSIST: 级联保存 -
void setAutos(Set<Auto> autos) { -
= autos; -
} -
void addGarageAuto(Auto auto) { -
auto.setGarage( -
-
} -
- }
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
- 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 { -
-
-
Integer autoId; -
String autotype; -
String autonum; -
Garage garage; -
-
@GeneratedValue -
Integer getAutoId() { -
autoId; -
} -
void setAutoId(Integer autoId) { -
= autoId; -
} -
String getAutotype() { -
autotype; -
} -
void setAutotype(String autotype) { -
= autotype; -
} -
String getAutonum() { -
autonum; -
} -
void setAutonum(String autonum) { -
= autonum; -
} -
-
-
Garage getGarage() { -
garage; -
} -
CascadeType.REMOVE:级联删除 ; CascadeType.REFRESH:级联刷新 -
void setGarage(Garage garage) { -
= garage; -
} -
- }
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; } }
单元测试方法
- @Test
public void update() { -
EntityManagerFactory factory = Persistence.createEntityManagerFacto ry( -
EntityManager em = factory.createEntityManager(); -
em.getTransaction().begin(); -
Garage garage = em.find(Garage. 1); -
garage.setGaragenum( -
-
em.getTransaction().commit(); -
em.close(); -
factory.close(); - }
@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(); }
运行观察
-
Hibernate:
select garage0_.gid asgid1_0_, asgarage0_.garagenum garagenum1_0_ fromGarage wheregarage0_ garage0_.gid=? -
Hibernate:
update Garage setgaragenum=? wheregid=?
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注解
- @OneToMany(cascade={CascadeType.PERSIST,CascadeType.MERGE},mappedBy="garage")
- public
Set<Auto> getAutos() { -
autos; - }
@OneToMany(cascade={CascadeType.PERSIST,CascadeType.MERGE},mappedBy="garage") public Set<Auto> getAutos() { return autos; }
将单元测试方法中的
- garage.setGaragenum("RoomAA");
garage.setGaragenum("RoomAA");
改一下
- garage.setGaragenum("RoomBB");
garage.setGaragenum("RoomBB");
运行update()
-
Hibernate:
select garage0_.gid asgid1_0_, asgarage0_.garagenum garagenum1_0_ fromGarage wheregarage0_ garage0_.gid=? -
Hibernate:
update Garage setgaragenum=? wheregid=?
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语句是一样的