You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot REST JPA粉丝表双用户外键复合主键实现方法

JPA粉丝表双外键复合主键实现方案

同表自关联场景下的双外键复合主键,和跨表关联的复合主键实现逻辑没有任何区别——复合主键本质是存储两个外键的关联ID值,和外键指向的表是否为同一张无关,直接按照JPA复合主键规范改造代码即可,不需要额外做特殊适配。


实现步骤

1. 定义复合主键嵌入类

新建主键类,满足三个要求:添加@Embeddable注解、实现Serializable接口、重写equals和hashCode方法,字段对应两个关联用户的ID:

import jakarta.persistence.Embeddable;
import java.io.Serializable;
import java.util.Objects;

@Embeddable
public class FollowersId implements Serializable {
    // 对应关注发起方用户ID,类型和User表主键类型保持一致
    private Integer fromUserId;
    // 对应被关注方用户ID
    private Integer toUserId;

    public FollowersId() {}

    public FollowersId(Integer fromUserId, Integer toUserId) {
        this.fromUserId = fromUserId;
        this.toUserId = toUserId;
    }

    // 自行生成两个字段的getter、setter方法

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        FollowersId that = (FollowersId) o;
        return Objects.equals(fromUserId, that.fromUserId) && Objects.equals(toUserId, that.toUserId);
    }

    @Override
    public int hashCode() {
        return Objects.hash(fromUserId, toUserId);
    }
}

如果你使用的是旧版JPA依赖,把代码中jakarta.persistence包路径替换为javax.persistence即可。

2. 改造Followers实体类

删除原有的独立自增ID字段,用@EmbeddedId声明复合主键,同时给两个外键关联字段添加@MapsId注解,绑定外键和复合主键内的对应字段:

import jakarta.persistence.*;

@Entity
public class Followers {
    @EmbeddedId
    private FollowersId id;

    @ManyToOne
    @MapsId("fromUserId") // 绑定复合主键中的fromUserId字段
    @JoinColumn(name = "from_user_fk")
    private User from;

    @ManyToOne
    @MapsId("toUserId") // 绑定复合主键中的toUserId字段
    @JoinColumn(name = "to_user_fk")
    private User to;

    public Followers() {};

    public Followers(User from, User to) {
        this.from = from;
        this.to = to;
        // 构造关联关系时同步给复合主键赋值
        this.id = new FollowersId(from.getId(), to.getId());
    }

    // 自行生成from、to字段的getter、setter方法
}

注意事项

  • User实体类不需要做任何修改,原有配置的@OneToMany粉丝、关注列表映射可以正常工作
  • 复合主键不需要配置生成策略,插入数据时只要给from、to两个字段赋值正确的User对象,JPA会自动拼装主键值
  • 该结构天然自带业务唯一性约束:同一个用户无法重复关注另一个用户,不需要额外添加唯一索引
  • 后续需要根据主键查询粉丝关系时,直接构造new FollowersId(发起关注用户ID, 被关注用户ID)调用findById方法即可,不需要编写复杂的关联查询

结构参考

当前旧表结构:
当前实现

改造后目标表结构:
目标实现


内容的提问来源于stack exchange,提问作者Derek Jafet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 04:48:04