在上一讲中jpa级联操作详解2 Garage.java中有一个CascadeType.REMOVE注解,是在删除garage表中数据的时候级联删除auto表中的数据;这次我们研究在Auto中有一个CascadeType.REMOVE注解时,在删除auto表中的数据的时候能否级联删除garage表中的数据
(一)不在Auto.java添加CascadeType.REMOVE注解时
数据库中的数据如下
mysql> select * from auto;
+--------+---------+----------+----------+
| autoId | autonum | autotype | garageid |
+--------+---------+----------+----------+
| 1 | hk2222 | car | 1 |
| 2 | bj0000 | car | 1 |
+--------+---------+----------+----------+
mysql> select * from garage;
+-----+-----------+
| gid | garagenum |
+-----+-----------+
| 1 | room1 |
+-----+-----------+
运行单元测试方法 delete2()
@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 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() {
return garage;
}
复原数据库中的数据为
mysql> select * from auto;
+--------+---------+----------+----------+
| autoId | autonum | autotype | garageid |
+--------+---------+----------+----------+
| 1 | hk2222 | car | 1 |
| 2 | bj0000 | car | 1 |
+--------+---------+----------+----------+
mysql> select * from garage;
+-----+-----------+
| gid | garagenum |
+-----+-----------+
| 1 | room1 |
+-----+-----------+
重新运行delete2()方法,测试成功
打开数据库,数据显示auto表和garage表中的相关数据都被删除了
mysql> select * from auto;
Empty set (0.00 sec)
mysql> select * from garage;
Empty set (0.00 sec)
回看一下这次发出的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方法中改为:只删除一条记录,这样就会出错
@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语句
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中的相应记录
delete from Garage where gid=?
但是由于还有一个外键关联相应的garage gid=1的记录,所以删除会报错
分享到:
相关推荐
本资料包"10_JPA详解_JPA中的一对多双向关联与级联操作.zip"聚焦于JPA中的一个重要概念——一对多双向关联及其级联操作。以下是对这一主题的详细阐述。 **一对多关联** 在关系数据库设计中,一对多关联是最常见的...
级联操作是JPA提供的一种特性,允许开发者指定当一个实体被持久化、更新、删除时,其关联的实体应该如何处理。这可以通过`CascadeType`枚举在`@OneToMany`注解中设置。例如,如果我们希望当用户被删除时,所有相关的...
3. 级联操作详解:阐述各种级联类型的含义和使用场景,以及如何在实体上设置级联策略。 4. 示例代码解析:提供具体的代码示例,展示如何在实体类中定义关联,并进行增删改查操作。 5. 性能优化建议:讨论如何通过...
本主题主要围绕"spring jpa操作数据库 级联数据 hibernate"展开,探讨如何利用Spring JPA进行数据库交互,并涉及到级联操作和与Hibernate的集成。 Spring JPA是Spring对Java Persistence API的一个封装,它提供了...
2. **级联操作(Cascading)**: 级联操作允许在一个实体的操作(如保存、删除)影响到与其关联的其他实体。`CascadeType`枚举提供了多种级联类型。 3. **外键约束(Foreign Key Constraints)**: JPA支持声明外键...
JPA支持懒加载和级联操作,比如在上述用户和订单的例子中,可以通过设置`mappedBy`属性实现懒加载,而级联操作如`CascadeType.ALL`可以在操作用户时同时处理关联的订单。 9. **实体状态管理** JPA定义了四种实体...
3. **级联操作**:级联是指当对一个实体进行某些操作(如保存、删除)时,这些操作会自动传播到与其关联的其他实体。例如,如果我们设置级联类型为`CascadeType.ALL`,那么删除一个用户时,与之关联的所有订单也会被...
- 如果希望在删除或更新Employee时,也影响到关联的Department,可以使用`@ManyToOne(cascade = CascadeType.ALL)`,指定级联操作类型。 6. **性能优化**: - 在处理大量数据时,考虑使用`@BatchSize`注解优化...
6. 实体关系管理:包括懒加载、EAGER加载,以及级联操作(CascadeType)。 7. CRUD操作:提供了基本的创建(create)、读取(read)、更新(update)、删除(delete)操作,以及保存(save)操作,可以同时处理新增...
- **级联操作**:可以通过`cascade`属性设置级联操作,如`CascadeType.ALL`表示对一方实体的操作(如删除、保存等)会级联到多方实体。 - ** orphanRemoval**:如果希望当一方实体移除时,关联的多方实体也被自动...
在`@OneToMany`注解中,我们使用了`cascade`属性,如`CascadeType.ALL`,这意味着对部门的操作(如保存、删除)会级联到相关的员工上。这使得我们可以一次性处理整个关联关系,简化了数据操作。 6. **性能考虑** ...
实体Bean之间的级联关系是Java持久化框架如Hibernate或JPA中的一个重要概念,它涉及到对象关系映射(ORM)中的数据操作同步性。在数据库中,实体Bean通常代表表中的行,而实体间的级联关系则反映了表之间的关联。...
`cascade = CascadeType.ALL`意味着对User的操作(如保存、删除)会自动应用到其关联的Order对象。 而在子实体(多端)上,通常不需要额外的注解,因为关联已经被父实体定义了。但是,为了完成双向关联,我们需要在...
在JPA中,一对多关系通过@OneToMany和@ManyToOne注解定义,级联操作如CascadeType.PERSIST、CascadeType.REMOVE允许在操作父对象时自动处理子对象的状态。 **11. JPA中的一对多延迟加载与关系维护(一对多关系:二...
`CascadeType.ALL`意味着对父实体进行的操作(如保存、更新、删除)会级联到所有子实体。`CascadeType.MERGE`则表示仅在合并父实体时更新子实体。开发者需要根据业务需求来选择合适的级联类型,以避免不必要的数据...
`fetch`定义加载策略,`cascade`定义级联操作,如保存、删除等是否影响关联的实体。 9. **@OneToOne, @OneToMany, @ManyToMany**:这三种注解分别用于定义一对一、一对多和多对多的关系映射,它们也包含fetch和...
例如,如果希望当删除学生时,自动删除所有关联的课程,可以在`@ManyToMany`上添加`cascade = CascadeType.REMOVE`。 ### 7. 性能优化 在处理大量关联时,需要考虑懒加载(Lazy Loading)和Eager加载(Eager ...