Hibernate如何将关联实体设为主键?实体映射问题求助
解决JPA中关联实体作为主键的映射问题
嘿,我懂你现在的困扰——直接把Currency实体作为AuditSystem的主键字段,JPA确实没法直接处理,因为它不知道怎么把整个实体映射到数据库的列里(毕竟数据库里的主键是字符串类型的code,不是整个实体对象)。下面给你两种可行的解决方案,你可以根据需求选:
方案一:使用@EmbeddedId(灵活扩展首选)
这种方法需要先定义一个可嵌入的主键类,用来对应数据库里的主键列,再关联到Currency实体:
1. 创建可嵌入的主键类
这个类要实现Serializable,并且包含和Currency主键一致的字段,还要重写equals和hashCode方法:
import lombok.AllArgsConstructor; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import jakarta.persistence.Embeddable; import java.io.Serializable; @Embeddable @NoArgsConstructor @AllArgsConstructor @EqualsAndHashCode public class AuditSystemId implements Serializable { // 和Currency的主键字段名完全一致 private String code; }
2. 修改AuditSystem实体
用@EmbeddedId标记主键,再通过@MapsId关联到Currency实体:
import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import jakarta.persistence.*; import java.sql.Timestamp; @Data @NoArgsConstructor @AllArgsConstructor @Entity @Table(name = "audit_system") public class AuditSystem { @EmbeddedId private AuditSystemId id; // @MapsId指定关联到主键类中的code字段 @MapsId("code") @OneToOne(fetch = FetchType.LAZY) @JoinColumn(name = "code") // 对应数据库里的外键列,和Currency的主键列名一致 private Currency currency; private Float audit; private Timestamp created; }
Currency实体不需要修改,保持原来的代码即可。
方案二:直接用主键字段关联(简洁首选)
如果AuditSystem的主键永远只关联Currency的code,可以不用创建额外的主键类,直接在AuditSystem里定义主键字段,再通过@MapsId关联实体:
import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import jakarta.persistence.*; import java.sql.Timestamp; @Data @NoArgsConstructor @AllArgsConstructor @Entity @Table(name = "audit_system") public class AuditSystem { // 直接用和Currency一致的主键字段 @Id private String code; // @MapsId告诉JPA这个关联实体的主键和当前实体的主键是同一个值 @MapsId @OneToOne(fetch = FetchType.LAZY) @JoinColumn(name = "code") private Currency currency; private Float audit; private Timestamp created; }
为什么原来的写法不行?
你之前直接把Currency作为@Id字段,JPA无法将整个实体对象映射到数据库的单一列中——数据库里的主键是字符串类型的code,而不是一个实体对象。所以必须明确主键的具体字段,再通过关联注解把实体和主键绑定起来。
内容的提问来源于stack exchange,提问作者fpiechowski
相关产品推荐
相关产品推荐

