级联保存的奇怪问题

Hibernate级联保存

同步:http://www.java1995.cn/blog/item/136

上一文cascadetype 讲解了使 用CascadeType的用处。

在一对多的时候,使用CascadeType.PERSIST 的时候,保存one方的时候,不会去保存many方。

设成CascadeType.ALL就可以

解决办法:

在Person表关系定义如下:
@ManyToOne(cascade = { CascadeType .PERSIST,CascadeType .MERGE})
@JoinColumn(name = "HOSPITAL_ID")

改为:
@ManyToOne()
@Cascade(value={CascadeType .SAVE_UPDATE})
@JoinColumn(name = "HOSPITAL_ID")

并把
import javax .persistence .CascadeType ;
import javax .persistence .Cascade;
改成
import org .hibernate .annotations .Cascade;
import org .hibernate .annotations .CascadeType ;

这样子就成功了。

在 JPA 中,级联保存(Cascade Persist)是一种非常常见的操作,用于在保存主实体时自动保存关联的子实体。配置和使用级联保存时,需要合理设置实体之间的关系以及级联操作的类型。 ### 配置方法 1. **使用 `@OneToMany` 或 `@OneToOne` 注解配置级联保存** 在实体类中,通过设置 `cascade = CascadeType.PERSIST` 来实现级联保存。例如: ```java @Entity public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @OneToMany(cascade = CascadeType.PERSIST) private List<ContactInfo> contactInfos; // getters and setters } ``` 2. **双向关联时,确保关系一致性** 在双向关联中,除了主实体配置级联保存,还需要在从实体中设置 `@ManyToOne` 并维护外键字段: ```java @Entity public class ContactInfo { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @ManyToOne @JoinColumn(name = "user_id") private User user; // getters and setters } ``` 3. **添加依赖** 确保在 `pom.xml` 中引入了 Spring Boot Starter Data JPA 依赖,以便 JPA 提供级联操作的支持: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> ``` ### 使用注意事项 1. **确保关系的双向维护** 在保存主实体之前,必须将子实体添加到主实体的集合中,同时设置子实体的主实体引用,以保证双向关系的一致性。例如: ```java User user = new User(); ContactInfo contactInfo = new ContactInfo(); contactInfo.setUser(user); user.getContactInfos().add(contactInfo); ``` 2. **避免无效的级联操作** 如果没有正确维护关系,例如未将子实体添加到主实体的集合中,级联保存将不会生效。同时,如果主实体未持久化,而子实体尝试引用主实体,可能会抛出异常。 3. **性能优化** 在某些情况下,JPA 会先插入子实体,然后更新外键字段,这可能会导致额外的数据库操作。例如,在 `@OneToMany` 关系中,如果主实体未管理外键,JPA 会先插入子实体,再通过 `update` 设置外键[^4]。 4. **避免循环引用** 如果实体之间存在循环引用,可能导致级联操作失败或性能问题。可以通过调整级联类型或使用 `@JsonManagedReference` 和 `@JsonBackReference` 来避免 JSON 序列化中的问题。 5. **级联类型的选择** 除了 `CascadeType.PERSIST`,还可以选择其他级联类型,例如 `CascadeType.REMOVE` 用于级联删除,`CascadeType.ALL` 表示所有操作都会级联。 ### 示例代码 以下是一个完整的示例,展示如何配置和使用 JPA 的级联保存功能: ```java @Entity public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; @OneToMany(cascade = CascadeType.PERSIST, orphanRemoval = true) private List<ContactInfo> contactInfos = new ArrayList<>(); // getters and setters } @Entity public class ContactInfo { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String email; @ManyToOne @JoinColumn(name = "user_id") private User user; // getters and setters } ``` 在业务逻辑中,保存用户及其联系信息: ```java User user = new User(); user.setName("John Doe"); ContactInfo contactInfo = new ContactInfo(); contactInfo.setEmail("john.doe@example.com"); contactInfo.setUser(user); user.getContactInfos().add(contactInfo); userRepository.save(user); ``` ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值