java - OneToOne 映射:违反参照完整性约束
问题描述
我正在使用 Spring Data JPA 开发 REST API,需要一些帮助。
我的 REST API 将处理创建组的请求,并根据请求数据将成员分配给组。请求的 URL 将是@PostMapping("/createGroup/{user-id}/groups")
我有以下课程,会员课程:
public class Member {
private int memberId;
private String memberName;
private String memberCity;
// getters / setters
我的请求正文类:
public class AppRequest {
private String name;
private String description;
private List<Member> members;
// getters / setters
我的集团实体:
@Entity
@Table(name="Groups")
public class GroupEntity {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
@OneToOne
@JoinColumn(name="groupOwnerId")
private MemberEntity groupOwnerId;
private String groupName;
private String description;
@ManyToMany(cascade=CascadeType.ALL)
@JoinTable(
name="Group_Members",
joinColumns= @JoinColumn(name="id"),
inverseJoinColumns= @JoinColumn(name="memberId")
)
Set<MemberEntity> members = new HashSet<>();
// getters / setters
我的会员实体:
@Entity
@Table(name="Members")
public class MemberEntity {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int memberId;
private String memberName;
private String memberCity;
@ManyToMany(cascade=CascadeType.ALL, mappedBy="members")
Set<GroupEntity> groups = new HashSet<>();
// getters / setters
最后是我的控制器,
@RestController
public class AppController {
@Autowired
MemberRepository memRepo;
@Autowired
GroupRepository groupRepo;
@PostMapping("/createGroup/{user-id}/groups")
@Transactional
public ResponseEntity<AppResponse> createGroup(@RequestBody AppRequest request,
@PathVariable(name="user-id") String userId) {
AppResponse response = new AppResponse();
GroupEntity group = new GroupEntity();
group.setGroupName(request.getName());
group.setDescription(request.getDescription());
// Code that causes error when trying to save owner ID
MemberEntity mem = new MemberEntity();
mem.setMemberId(Integer.parseInt(userId));
group.setGroupOwnerId(mem);
List<Member> members = request.getMembers();
Set<MemberEntity> storedMembers = new HashSet<>();
Set<GroupEntity> storedGroups = new HashSet<>();
storedGroups.add(group);
for(Member member : members) {
if(member.getMemberId() != 0) { // existing member
MemberEntity memberentity = new MemberEntity();
memberentity.setMemberName(member.getMemberName());
memberentity.setMemberCity(member.getMemberCity());
storedMembers.add(memberentity);
memberentity.setGroups(storedGroups);
memRepo.save(memberentity);
}
else { // new member
//some logic
}
group.setMembers(storedMembers);
groupRepo.save(group);
}
return null;
}
}
请求正文将是这样的,
{
"description": "Funny Group",
"members": [
{
"memberCity": "Mumbai",
"memberName": "Amit"
},
{
"memberId": 123
}
],
"name": "My Group"
}
我想要实现的是在创建组时,我想在 REST URL [/createGroup/{user-id}/groups] 中添加用户 ID 作为该组的所有者 ID。为了实现这一点,我手动创建了一个成员实体并将其设置为 groupOwnerId,如下所示,
MemberEntity mem = new MemberEntity();
mem.setMemberId(Integer.parseInt(userId));
group.setGroupOwnerId(mem);
如果我在上面的代码应用程序启动但 groupOwnerId 值设置为 null 这很明显,因为我没有在任何地方设置它。因此,如果我编写上面的代码,应用程序将正确启动。但是当我到达终点时,我得到以下错误,
org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: Referential integrity constraint violation: "FKB0L8UXRYL2TEVI7BTCMI4BYOD: PUBLIC.""GROUPS"" FOREIGN KEY(GROUP_OWNER_ID) REFERENCES PUBLIC.MEMBERS(MEMBER_ID) (12345)"; SQL statement:
insert into groups (id, description, group_name, group_owner_id) values (null, ?, ?, ?)
我试图弄清楚如何正确地进行映射,以便可以从 URL 映射 groupOwnerId。并且新成员也会使用自动生成的 ID 保存到数据库中。
我目前正在使用 H2 数据库,但最终会迁移到 MySQL 或 Oracle。
请让我知道你们是否可以帮助决定解决此问题的方法。
解决方案
首先,我会为组和用户资源使用以下 URL 模式:
/groups/{groupId}
/users/{userId}
这将允许您分别创建用户和组,因为组可以在没有任何用户的情况下存在,而用户可以在不成为组成员的情况下存在。
像往常一样,对 /groups/ 进行 POST 操作以创建组,对 /users/ 进行 POST 操作以创建用户。
创建组和用户后,我将检索这两个实体(或使用 POST 操作返回的实体)来设置组的组所有者并创建组的 JSON(或 XML)表示。
然后将 JSON 表示放入 URL /groups/{groupId}(在 URL 中插入组的实际 ID),以便将组与新的组所有者保持一致。
希望这可以帮助!
推荐阅读
- database - SequoiaDB导入工具如何使用?
- php - 检查一个数组的值是否存在于另一个数组中
- javascript - Javascript将地理位置作为字符串变量传递
- android - Activity 中的奇怪行为 ViewModel 观察者调用方法 - MVVM 架构
- python - 如何在 Python 3 中将 PNG 数据的 hexdump 字符串转换为二进制?
- javascript - 如何修复设备相机不支持移动浏览器 React Js 的问题
- redis - Redis在redis服务器启动/重启时删除和设置密钥
- c# - 如何在调整窗口大小时保持视频播放器的宽高比适合屏幕
- php - 无法在 php 文件中获取值
- java - 如何使用数据库中已经存在的另一个命名(配置文件)自定义表角色(特权)?