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

如何在Hibernate继承关系中为子类PoliceMan设置独立主键police_id?

问题描述

问题描述图

我定义了Person父类:

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "PERSON")
public class Person {
    @Id
    @Column(name = "person_id")
    @SequenceGenerator(sequenceName = "PERSON_ID_SEQ", allocationSize = 1, name="PERSON_ID_SEQ")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "PERSON_ID_SEQ")
    private Long personId;
    
    private String name;
}

以及继承自Person的PoliceMan子类:

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "POLICE_MAN")
public class PoliceMan extends Person{
    @Id
    @Column(name = "police_id")
    private Long policeId;
    
    private String something;
}

问题:父类Person已使用@Id注解,子类PoliceMan无法再用@Id将police_id设为独立唯一标识,该如何解决?

已参考过Hibernate继承相关内容,但仍未解决问题。


解决方案

根据你的需求,分两种场景给出具体解决方式:

场景1:保留继承关系,子类主键关联父类主键

这种场景下,子类PoliceMan作为特殊的Person实例,使用JOINED继承策略,子类表的主键同时作为关联父类表的外键:

  1. 修改父类Person,指定继承策略
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "PERSON")
@Inheritance(strategy = InheritanceType.JOINED)
public class Person {
    @Id
    @Column(name = "person_id")
    @SequenceGenerator(sequenceName = "PERSON_ID_SEQ", allocationSize = 1, name="PERSON_ID_SEQ")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "PERSON_ID_SEQ")
    private Long personId;
    
    private String name;
}
  1. 调整子类PoliceMan的主键映射
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "POLICE_MAN")
@PrimaryKeyJoinColumn(name = "police_id", referencedColumnName = "person_id")
public class PoliceMan extends Person{
    // 移除子类的@Id注解,police_id会同时作为子类主键和关联父类的外键
    private String something;
}

场景2:仅复用父类属性,子类完全独立拥有主键

如果你的核心需求只是复用Person的属性,不需要将PoliceMan视为Person的实体子类,可将父类改为映射超类:

  1. 修改父类为非实体的映射超类
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@MappedSuperclass
public class Person {
    // 移除@Id、@Entity等实体相关注解,仅保留属性映射
    private String name;
}
  1. 子类定义独立主键
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "POLICE_MAN")
public class PoliceMan extends Person{
    @Id
    @Column(name = "police_id")
    // 可根据需求添加主键生成策略,比如@GeneratedValue
    private Long policeId;
    
    private String something;
}

额外说明

如果坚持要让police_id和person_id完全独立且保留继承关系,这种设计不符合ORM继承的语义(继承代表"is-a"关系,子类实例本质是父类实例的扩展),建议放弃继承,改为用@OneToOne或@ManyToOne关联Person类,实现两者独立主键的关联。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 21:25:14