Spring Boot创建继承类JPA实体报错 父类字段无法持久化问题
问题诊断
你的代码存在3处关键错误,直接导致父类字段无法持久化:
- 父类缺少JPA继承映射注解
JPA默认不会持久化普通父类的字段,当前Users类只是普通POJO,没有任何JPA映射标记,框架扫描UserDetails实体时只会读取子类自身声明的字段,父类的userId/username/email/password会被直接忽略,不会生成对应的数据库表字段。 - Lombok注解和继承搭配存在逻辑缺陷
你在子类上标注的@Data、@AllArgsConstructor默认不会处理父类的字段:@AllArgsConstructor生成的全参构造仅包含子类自身的uId/description等字段,实例化时无法给父类字段赋值,容易出现父类字段为null的情况@Data生成的equals()、hashCode()、toString()方法不会包含父类字段,后续做对象比较、日志打印时会出现逻辑错误
- 主键缺少生成策略
子类中标记为主键的uId字段没有配置主键生成规则,插入数据时如果不手动赋值,会触发主键为空的报错。
修正方案
如果你的需求是复用父类的通用字段,所有字段都持久化到UserDetails对应的同一张数据库表中,按如下方式修改即可:
1. 修改父类代码
给父类添加@MappedSuperclass注解,标记该类是实体类的公共父类,字段会被子类实体继承持久化,同时补充Lombok注解保证字段可正常访问:
@MappedSuperclass @Data @NoArgsConstructor @AllArgsConstructor public class Users { Long userId; String username; String email; String password; }
注意:如果需要
Users本身也作为独立实体映射单独的表,需要替换@MappedSuperclass为@Entity,同时搭配@Inheritance注解选择继承映射策略,这种场景不适合当前的字段复用需求。
2. 修改子类代码
补充Lombok继承相关的注解配置,给主键添加自增策略,去掉不必要的@AllArgsConstructor(如果需要全参构造包含父类字段,可替换为@SuperBuilder或手动编写构造方法):
@Entity @Data @NoArgsConstructor @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class UserDetails extends Users { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) Long uId; String description; String postalAddress; Long postalCode; }
补充说明
- 修正后启动项目,JPA会自动在
UserDetails对应的表中生成父类定义的4个字段,可正常持久化读写 - 如果项目中使用Lombok的
@Builder注解,父子类都需要添加@SuperBuilder注解,否则builder模式无法设置父类字段值 - 父类字段如果设置为
private访问权限也不影响持久化,只要保证字段有对应的get/set方法即可(@Data会自动生成)
内容的提问来源于stack exchange,提问作者Mussawir Ahmad Paul
相关产品推荐
相关产品推荐

