JPA能否使用@Embeddable嵌套类中定义的@Id作为外层实体的主键
可以实现,但你当前的注解配置不符合JPA规范,需要调整,以下是两种不需要复合主键的可行方案:
方案1:复用现有@Embeddable结构
你现有代码的问题是@Embeddable类中使用@Id是无效的,@Id注解仅对@Entity标注的实体类生效,且当前CPU实体没有声明主键,启动会直接报错,调整方式如下:
- 修改Metric类,移除无效的主键注解
@Embeddable public class Metric { private long metricId; private OffsetDateTime time; private String workflowId; private String jobId; private String name; // 补充getter、setter方法 }
- 修改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
相关产品推荐
相关产品推荐

