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

}
相关推荐
liangbo73 分钟前
01-JVM 内存模型全景
java·jvm
橘子编程4 分钟前
Java邮件发送全攻略:从入门到实战
java·开发语言·spring boot·spring·spring cloud·maven
阿哉7 分钟前
一次 Lombok 静默失效排查:JDK 23 注解处理默认策略变更引发的满屏「找不到符号」
java
纪伊路上盛名在8 分钟前
了解一点Docker
java·docker·容器
掘金者阿豪10 分钟前
Let‘s Encrypt 证书到底会不会自动续期?从一次服务器迁移后的证书排查说起
后端
码农阿豪10 分钟前
Seedance 2.0/2.5 虚拟素材能跨 Key 共用吗?一次讲清 Asset ID、账号隔离与 SaaS 素材架构
java·运维·架构
Meta3915 分钟前
Java八股文之Spring Boot中解决Redis和MySQL的数据一致性问题
java·spring boot·redis
joinwell5217 分钟前
Agent 中断后,原任务如何安全接管?从恢复标记到效果事实
人工智能·后端·架构
sp4229 分钟前
羽量级的 Java Bean 实体校验器
后端
魔兽大山哥35 分钟前
【NL2SQL 实战 07】LIMIT 不是小事:默认 100 行背后的产品判断
后端