改造CPRQ设计后JPARepository保存实体未完整存储继承自基类的公共字段
问题核心原因
按照JPA的默认扫描规则,框架只会直接扫描标注了@Entity的实体类本身定义的字段和映射配置,不会向上递归读取父类的字段、@Column这类注解配置。就算父类上写了完整的列映射,没有特殊标识的话,这些配置会被框架完全忽略,最终生成的保存SQL只会包含子类自己定义的id、first_name字段,父类的两个公共字段压根不会出现在SQL里,自然也就没法存进数据库。
已验证的解决方案
在公共基类ABaseEntity上添加@MappedSuperclass注解即可解决问题,这个注解就是JPA专门为“多实体抽公共父类字段”场景设计的:
- 标注为
@MappedSuperclass的类本身不会被映射成独立的数据库表 - 所有继承这个类的实体,都会自动继承类上定义的所有字段、列映射规则、约束配置,框架扫描子类实体的时候会把父类的字段一并纳入持久化范围
- 调整后的基类代码核心结构:
@MappedSuperclass public class ABaseEntity { public ABaseEntity() { } public ABaseEntity(int tenantIdpkfk, int status) { this.tenantIdpkfk = tenantIdpkfk; this.status = status; } @Column(name = "tenantIDPKFK") private Integer tenantIdpkfk; @Column(name = "status") private Integer status; }
实操注意事项
- 不要给这个基类加
@Entity注解,否则框架会把它识别成独立的实体,自动生成无关的数据库表,完全违背抽公共属性的设计目的 - 基类里的私有字段必须配套写getter、setter方法,JPA是靠反射读写字段值的,没有访问方法的话就算加了注解,字段也没法正常完成读写映射
- 这套抽公共基类的模式适合所有跨实体复用的通用属性(租户ID、逻辑状态、创建时间、更新时间这类),后续要做统一的租户隔离、状态过滤逻辑,直接在基类里实现就行,不用在每个子实体里重复写一遍代码
内容的提问来源于stack exchange,提问作者Siddharth
相关产品推荐
相关产品推荐

