【@MappedSuperclass】 子类实体继承父类的通用字段持久化为 null

前言

在平时开发中,在模型设计的时候,会有一些通用的字段,比如id,创建时间,更新时间等通用的字段。在模型设计时就可以不用考虑这些字段,直接写一个父类继承就行,往往一般这些公司框架已经写好一个通用的父类了,那我还有一些字段需要抽出来怎么办,那就再加一层,没有什么是加一层解决不了的。

儿子-->父亲-->爷爷

坑来了。儿子可以正常持久化,爷爷可以正常持久化,父亲持久化的数据全部为 null。怎么回事?

正文

实体类

通用实体类

java 复制代码
@DynamicInsert
@DynamicUpdate
@MappedSuperclass
@Data
public class BaseDomainEntity {

    @Id
    @Column(name = "id")
    @ApiModelProperty(value = "唯一标识")
    protected String id;

    @Column(name = "created_by")
    @ApiModelProperty(value = "创建人")
    protected String createdBy;

    @Column(name = "created_date")
    @ApiModelProperty(value = "创建时间")
    protected Date createdDate;

    @Column(name = "last_modified_by")
    @ApiModelProperty(value = "最后修改人")
    protected String lastModifiedBy;

    @Column(name = "last_modified_date")
    @ApiModelProperty(value = "最后更新时间")
    protected Date lastModifiedDate;

}

父亲

java 复制代码
@Data
@ApiModel(value = "父亲")
public class Parent {

    @Column(name = "name")
    @ApiModelProperty(value = "姓名")
    private String name;

    @Column(name = "age")
    @ApiModelProperty(value = "年龄")
    private String age;

    @Column(name = "sex")
    @ApiModelProperty(value = "性别")
    private String sex;

}

儿子

java 复制代码
@Data
@Entity
@Table(name = "son")
@ApiModel(value = "儿子")
public class Son {

    @Column(name = "interest")
    @ApiModelProperty(value = "兴趣")
    private String interest;

    @Column(name = "hobby")
    @ApiModelProperty(value = "爱好")
    private String hobby;

}

service

java 复制代码
    public void test() {
        Son son = new Son();
        son.setHobby("打篮球");
        son.setInterest("打篮球");
        initParent(son);
        repository.save(son);
    }

    private void initParent(Parent parent) {
        parent.setAge("18");
        parent.setName("小明");
        parent.setSex("男");
    }
  • 因为通用实体字段有@DynamicInsert、@DynamicUpdate这两个注解,且已经实现了自动填充,所以通用的实体已经成功持久化,Son 儿子也已经成功持久化,唯独 Parent 这个父类的字段全部为 null 的。为什么?
  • 重点就是@MappedSuperclass这个注解

@MappedSuperclass的作用

  • 标识父类:这个注解通常用于标识一个类是其他实体类的父类。
  • 代码复用和模型分离:在项目开发中,如果多个实体类有共同的属性,可以使用@MappedSuperclass注解将这些属性封装到一个父类中。例如,数据库表中都需要id来表示编号,id是这些映射实体类的通用的属性,交给jpa统一生成主键id编号,那么使用一个父类来封装这些通用属性,并用@MappedSuperclass标识。
  • 不映射到数据库表:标注为@MappedSuperclass的类将不是一个完整的实体类,他将不会映射到数据库表,但是他的属性都将映射到其子类的数据库字段中。
  • 不能再标注@Entity或@Table注解:标注为@MappedSuperclass的类不能再标注@Entity或@Table注解,也无需实现序列化接口。
  • 这样可以提高代码的复用性和可维护性,减少代码重复。

修改父类

java 复制代码
@Data
@ApiModel(value = "父亲")
@MappedSuperclass
public class Parent {

    @Column(name = "name")
    @ApiModelProperty(value = "姓名")
    private String name;

    @Column(name = "age")
    @ApiModelProperty(value = "年龄")
    private String age;

    @Column(name = "sex")
    @ApiModelProperty(value = "性别")
    private String sex;

}
相关推荐
快乐就好ya1 分钟前
xxl-job分布式定时任务
java·分布式·spring cloud·springboot
沉默的煎蛋8 分钟前
MyBatis 注解开发详解
java·数据库·mysql·算法·mybatis
Aqua Cheng.8 分钟前
MarsCode青训营打卡Day10(2025年1月23日)|稀土掘金-147.寻找独一无二的糖葫芦串、119.游戏队友搜索
java·数据结构·算法
京东零售技术12 分钟前
一次线上生产库的全流程切换完整方案
后端
石明亮(JT)25 分钟前
docker部署jenkins
java·docker·jenkins
我们的五年27 分钟前
【C语言学习】:C语言补充:转义字符,<<,>>操作符,IDE
c语言·开发语言·后端·学习
翻晒时光36 分钟前
Java 多线程与并发:春招面试核心知识
java·jvm·面试
小张认为的测试37 分钟前
Jenkins邮件通知的详细配置含邮件通知模板!
java·servlet·ci/cd·jenkins·邮件通知
灯火不休ᝰ39 分钟前
[java] java基础-字符串篇
java·开发语言·string
励志去大厂的菜鸟42 分钟前
系统相关类——java.lang.Math (三)(案例详细拆解小白友好)
java·服务器·开发语言·深度学习·学习方法