JPA中外键存储在子表的一对一映射实体类编写求助
JPA 外键存子表的一对一关联级联保存实现
你需要分别编写父表、子表对应的实体类,核心是关联注解的配置,具体实现如下:
父实体类(对应 parent_price 表)
父表无外键,作为关联关系的被维护端,配置序列生成主键,同时指定关联的级联保存规则:
import javax.persistence.*; import java.math.BigDecimal; @Entity @Table(name = "parent_price") public class ParentPrice { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "parent_price_seq") // sequenceName 替换为你实际数据库中的序列名 @SequenceGenerator(name = "parent_price_seq", sequenceName = "PARENT_PRICE_ID_SEQ", allocationSize = 1) private Long id; // 按需添加父表其他业务字段 private String priceName; private BigDecimal basePrice; // mappedBy值为子实体中关联父实体的属性名,配置级联持久化实现保存父时自动存子 @OneToOne(mappedBy = "parentPrice", cascade = CascadeType.PERSIST, fetch = FetchType.LAZY) private ChildPrice childPrice; public ParentPrice() {} // 关联关系绑定方法,自动维护双向关联一致性 public void setChildPrice(ChildPrice childPrice) { this.childPrice = childPrice; if (childPrice != null) { childPrice.setParentPrice(this); } } // 其他getter、setter方法按需添加 public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getPriceName() { return priceName; } public void setPriceName(String priceName) { this.priceName = priceName; } public BigDecimal getBasePrice() { return basePrice; } public void setBasePrice(BigDecimal basePrice) { this.basePrice = basePrice; } public ChildPrice getChildPrice() { return childPrice; } }
子实体类
子表存储外键,作为关联关系的维护端,配置外键字段映射:
import javax.persistence.*; import java.math.BigDecimal; import java.time.LocalDate; @Entity @Table(name = "child_price") public class ChildPrice { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; // 按需添加子表其他业务字段 private BigDecimal discountPrice; private LocalDate effectiveDate; // name值为子表中外键字段的实际名称,unique保证一对一关联唯一性 @OneToOne @JoinColumn(name = "parent_price_id", unique = true, nullable = false) private ParentPrice parentPrice; public ChildPrice() {} // getter、setter方法按需添加 public Long getId() { return id; } public void setId(Long id) { this.id = id; } public BigDecimal getDiscountPrice() { return discountPrice; } public void setDiscountPrice(BigDecimal discountPrice) { this.discountPrice = discountPrice; } public LocalDate getEffectiveDate() { return effectiveDate; } public void setEffectiveDate(LocalDate effectiveDate) { this.effectiveDate = effectiveDate; } public ParentPrice getParentPrice() { return parentPrice; } public void setParentPrice(ParentPrice parentPrice) { this.parentPrice = parentPrice; } }
使用示例
保存父实体时即可自动级联保存关联的子实体:
// 构造父实体 ParentPrice parent = new ParentPrice(); parent.setPriceName("生鲜类定价"); parent.setBasePrice(new BigDecimal("120")); // 构造子实体 ChildPrice child = new ChildPrice(); child.setDiscountPrice(new BigDecimal("96")); child.setEffectiveDate(LocalDate.of(2024, 7, 1)); // 绑定关联关系 parent.setChildPrice(child); // 仅保存父实体,子实体会自动持久化到数据库 parentPriceRepository.save(parent);
注意事项
- 如果需要级联更新、删除操作,可以将
cascade属性调整为CascadeType.ALL,按需选择级联类型即可 mappedBy属性不能写错,必须和子实体中关联父实体的属性名完全一致,否则会出现关联映射错误- 子实体
@JoinColumn的unique配置可以避免出现一对多的脏数据,保证一对一关联的正确性
内容的提问来源于stack exchange,提问作者zamming
相关产品推荐
相关产品推荐

