发布于2026-04-19 阅读(0)
扫一扫,手机访问

在 Spring R2DBC 中,若实体(如 tutor_student 关联表)拥有由多个字段组成的复合主键(如 relation_id + tutor_id),需通过 @IdClass 显式声明主键结构,否则 ReactiveCrudRepository.save() 会误判为新记录而执行插入而非更新。
在 Spring R2DBC 中,若实体(如 `tutor_student` 关联表)拥有由多个字段组成的复合主键(如 `relation_id` + `tutor_id`),需通过 `@IdClass` 显式声明主键结构,否则 `ReactiveCrudRepository.save()` 会误判为新记录而执行插入而非更新。
Spring R2DBC 虽不支持 JPA 的 @EmbeddedId,但完全兼容 @IdClass 注解——这是官方推荐的复合主键解决方案。关键在于:主键字段必须同时满足三个条件:
以下是完整、可运行的配置示例:
// 主键类:必须包含所有@Id字段,且实现Serializable
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class TutorStudentId implements Serializable {
private Long relationId;
private Long tutorId;
// 建议重写equals/hashCode(R2DBC虽不强制,但利于业务逻辑一致性)
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
TutorStudentId that = (TutorStudentId) o;
return Objects.equals(relationId, that.relationId) &&
Objects.equals(tutorId, that.tutorId);
}
@Override
public int hashCode() {
return Objects.hash(relationId, tutorId);
}
}// 实体类:使用@IdClass并标注每个主键字段
@Getter
@Setter
@NoArgsConstructor
@Table("tutor_student")
@IdClass(TutorStudentId.class)
public class TutorStudentEntity {
@Id
@Column("relation_id")
private Long relationId;
@Id
@Column("tutor_id")
private Long tutorId;
@Column("student_id")
private String studentId;
@Column("status")
private String status;
}✅ 验证更新行为:
当调用 repository.save(new TutorStudentEntity(1L, 101L, "S001", "ACTIVE")) 时,R2DBC 会基于 relationId=1L 和 tutorId=101L 查询是否存在匹配记录。若存在,则执行 UPDATE;否则执行 INSERT——这正是 save() 方法的语义保障。
⚠️ 重要注意事项:
通过上述配置,即可在响应式栈中安全、准确地管理复合主键的多对多关联实体,兼顾数据一致性与操作语义的清晰性。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8