Spring Data Rest中单事务级联保存关联实体的实现问题
解决Spring Data Rest下OneToOne实体级联保存问题
你遇到的问题核心在于双向OneToOne关联的维护端设置以及Spring Data Rest的默认行为——Spring Data Rest只会遵循JPA中关系维护端的级联规则,而你的当前配置里,关系维护端是Address(因为它带有@JoinColumn注解),而你POST的是Restaurant(关系被维护端),所以级联保存不会触发。
下面是无需自定义RestController的解决方案:
1. 调整关联维护端到Restaurant
将关系维护端切换到Restaurant,这样当你POSTRestaurant实体时,JPA的CascadeType.ALL会生效,Spring Data Rest也会自动处理嵌套的Address实体的级联保存,且所有操作在同一个事务中,失败则统一回滚。
修改后的实体代码:
Restaurant类
@Entity @Table(name = "RESTAURANT") public class Restaurant extends BaseEntity { private String name; private Address address; public Restaurant() { } @Column(name = "NAME", nullable = false, unique = true) public String getName() { return name; } public void setName(String name) { this.name = name; } // 改为关系维护端,添加JoinColumn并保留级联配置 @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true) @JoinColumn(name = "ADDRESS_ID") // 在RESTAURANT表中新增外键列关联ADDRESS public Address getAddress() { return address; } public void setAddress(Address address) { if (address == null) { if (this.address != null) { this.address.setRestaurant(null); } } else { address.setRestaurant(this); } this.address = address; } }
Address类
@Entity @Table(name = "ADDRESS") public class Address extends BaseEntity { private String title; private Restaurant restaurant; @Column(name = "TITLE") public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } // 改为关系被维护端,使用mappedBy指向Restaurant的address属性 @OneToOne(fetch = FetchType.LAZY, mappedBy = "address") public Restaurant getRestaurant() { return restaurant; } public void setRestaurant(Restaurant restaurant) { this.restaurant = restaurant; } }
2. 测试验证
现在你再次POST如下JSON到http://localhost:8088/restaurants:
{ "name":"restaurant name", "address":{ "title":"asli" } }
Spring Data Rest会在同一个事务中同时保存Restaurant和Address,如果任何一步失败,整个事务会回滚,不会留下部分持久化的实体。
关键说明
orphanRemoval = true是可选配置,它会确保当你删除Restaurant或把address设为null时,对应的Address也会被自动删除,适合一对一强关联的场景。- Spring Data Rest默认只识别关联维护端的级联操作,所以调整维护端是核心解决思路,不需要额外自定义Controller,完全依托Spring Data JPA和Rest的自动能力。
内容的提问来源于stack exchange,提问作者Fazel Farnia
相关产品推荐
相关产品推荐

