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

JPA能否使用@Embeddable嵌套类中定义的@Id作为外层实体的主键

可以实现,但你当前的注解配置不符合JPA规范,需要调整,以下是两种不需要复合主键的可行方案:

方案1:复用现有@Embeddable结构

你现有代码的问题是@Embeddable类中使用@Id是无效的,@Id注解仅对@Entity标注的实体类生效,且当前CPU实体没有声明主键,启动会直接报错,调整方式如下:

  1. 修改Metric类,移除无效的主键注解
@Embeddable
public class Metric {
    private long metricId;
    private OffsetDateTime time;
    private String workflowId;
    private String jobId;
    private String name;
    // 补充getter、setter方法
}
  1. 修改CPU实体,将嵌入类的metricId映射为主键
@Entity
@Table(name = "metrics")
public class CPU {
    @Enumerated(EnumType.STRING)
    private final MetricType metricType = MetricType.CPU;
    
    @Embedded
    private Metric metric;

    // 将嵌入类的metricId暴露为实体主键
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Long getMetricId() {
        return metric != null ? metric.getMetricId() : null;
    }

    public void setMetricId(Long metricId) {
        if (metric == null) {
            metric = new Metric();
        }
        metric.setMetricId(metricId);
    }
    // 补充其他getter、setter方法
}

方案2:改用@MappedSuperclass实现(更简洁)

如果你的核心需求是复用Metric类的公共字段定义,用@MappedSuperclass比@Embeddable更适配这个场景,代码更简洁,不需要额外处理主键映射:

@MappedSuperclass
public class Metric {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long metricId;
    private OffsetDateTime time;
    private String workflowId;
    private String jobId;
    private String name;
    // 补充getter、setter方法
}

@Entity
@Table(name = "metrics")
public class CPU extends Metric {
    @Enumerated(EnumType.STRING)
    private final MetricType metricType = MetricType.CPU;
    // 补充getter、setter方法
}

两种方案都不需要创建复合主键,且完全兼容你现有的数据库表结构。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 23:39:03