Spring Boot中继承关系下实体关联映射问题咨询
问题解答
1. Request作为Entity时,能否使用@Embeddable和@Embedded?
不行。@Embeddable和@Embedded是JPA用于值类型嵌入的注解,这类组件没有独立的数据库表,其属性会直接嵌入到宿主实体的表字段中。而Request是独立的Entity,有自己的数据库表,需要通过实体关联注解(@OneToMany/@ManyToOne)来建立与Submitter的关系,而非嵌入。
2. 继承场景下双向一对多关联的正确实现方式
从你描述的Submitter表仅存id来看,推测你用的是联合表继承策略(父表User存储所有共享属性,子表Submitter仅存主键作为外键关联父表),以下是具体实现步骤和代码示例:
步骤1:定义父类User(联合表继承策略)
@Entity @Table(name = "user") @Inheritance(strategy = InheritanceType.JOINED) // 父表存共享属性,子表仅存关联主键 public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String username; private String email; // 其他共享属性(如手机号、创建时间等) // 构造器、getter、setter省略 }
步骤2:定义Submitter子类
@Entity @Table(name = "submitter") @PrimaryKeyJoinColumn(name = "id") // 指定子表主键与父表主键的关联列 public class Submitter extends User { // 继承User的所有属性,无需重复定义 // 双向一对多关联Request @OneToMany(mappedBy = "submitter", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY) private List<Request> requests = new ArrayList<>(); // 辅助方法:维护关联一致性,避免持久化异常 public void addRequest(Request request) { requests.add(request); request.setSubmitter(this); } public void removeRequest(Request request) { requests.remove(request); request.setSubmitter(null); } // getter、setter省略 }
步骤3:定义Request实体(双向关联的另一端)
@Entity @Table(name = "request") public class Request { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String title; private String content; // 其他请求属性(如状态、创建时间等) // 多对一关联Submitter @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "submitter_id", nullable = false) // 外键列,关联submitter表的id private Submitter submitter; // 构造器、getter、setter省略 }
关键注意点
- 继承策略调整:如果不需要单独的Submitter表,也可以用
InheritanceType.SINGLE_TABLE(单表继承),此时所有用户类型的属性都存在user表,通过discriminator列区分类型,你可以根据业务需求选择。 - 关联一致性:双向关联必须通过辅助方法(如
addRequest)同步两端的关联关系,否则会出现持久化时的关联数据不一致问题。 - 加载策略:建议将
@ManyToOne的fetch改为LAZY,避免默认EAGER加载带来的不必要性能开销,@OneToMany默认是LAZY,符合大多数场景需求。
内容的提问来源于stack exchange,提问作者Altaf
相关产品推荐
相关产品推荐

