【@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;

}
相关推荐
子兮曰1 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
小羊没烦恼!1 天前
微服务化的基石——持续集成
java·大数据·word·powerpoint·.net
子兮曰1 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
俊昭喜喜里1 天前
java中的继承和多态的区别
java
小羊没烦恼!1 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
爱勇宝1 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
譕痕1 天前
JSONObject与JSONArray封装数据格式区别
java·json
胡写代码1 天前
别再前后端各写一套表单校验了
java·后端
小鱼能吃糖1 天前
缺陷修复总览 · mall电商项目:5类缺陷,1个病根,4个业务域
java·电商
此时不提桶,更待何时1 天前
01-06-A-JVM排查实战详解
java·jvm