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

Hibernate如何实现复合主键对应的复合外键映射配置

实现方案

首先你需要先确保复合主键类UserID符合JPA规范,代码示例如下:

import java.io.Serializable;
import java.util.Objects;

public class UserID implements Serializable {
    private int id;
    private String name;

    // 无参构造
    public UserID() {}

    public UserID(int id, String name) {
        this.id = id;
        this.name = name;
    }

    // 重写equals和hashCode
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        UserID userId = (UserID) o;
        return id == userId.id && Objects.equals(name, userId.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name);
    }

    // getters and setters
}

然后根据你的业务需求选择以下两种关联方式即可:

场景1:UserDetails与User为一对一关联,id和name既是UserDetails的主键也是外键

改造后的UserDetails代码如下:

import javax.persistence.*;
import java.io.Serializable;

@Entity
@Table(name = "userdetails")
@IdClass(UserID.class) // 复用复合主键类
public class UserDetails implements Serializable {

    @Id
    private int id;
    @Id
    private String name;

    private String address;
    private String otherFields;

    // 定义关联关系
    @OneToOne
    @JoinColumns(
        value = {
            @JoinColumn(name = "id", referencedColumnName = "id", insertable = false, updatable = false),
            @JoinColumn(name = "name", referencedColumnName = "name", insertable = false, updatable = false)
        }
    )
    private User user;

    // getters and setters
}

场景2:UserDetails有独立主键,id和name仅作为关联User的外键

改造后的UserDetails代码如下:

import javax.persistence.*;
import java.io.Serializable;

@Entity
@Table(name = "userdetails")
public class UserDetails implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long detailsId; // 独立主键

    private int id;
    private String name;

    private String address;
    private String otherFields;

    // 若一个用户对应多个详情就用@ManyToOne,一对一就用@OneToOne
    @ManyToOne
    @JoinColumns(
        value = {
            @JoinColumn(name = "id", referencedColumnName = "id", insertable = false, updatable = false),
            @JoinColumn(name = "name", referencedColumnName = "name", insertable = false, updatable = false)
        }
    )
    private User user;

    // getters and setters
}

关键说明

  • @JoinColumns注解用于指定多列外键关联,每个@JoinColumn的name属性对应userdetails表的字段名,referencedColumnName对应users表的关联字段名
  • 设置insertable = false, updatable = false是为了避免字段重复映射,你只需要给id、name属性赋值即可自动维护外键关联

内容的提问来源于stack exchange,提问作者Harshit Vijayvargia

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 21:15:05