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

}
相关推荐
白緢3 分钟前
嵌入式 Linux + 内核开发高频问题及排查
java·linux·运维
Flandern11119 分钟前
Go程序员学习AI大模型项目实战02:给 AI 装上“大脑”:从配置解包到流式生成的深度拆解
人工智能·后端·python·学习·golang
juniperhan15 分钟前
Flink 系列第4篇:Flink 时间系统与 Timer 定时器实战精讲
java·大数据·数据仓库·flink
超级大只老咪17 分钟前
一维度前缀和解题通用模板(java)
java·开发语言·算法
历程里程碑24 分钟前
1 . Git本地操作:版本控制 跨平台协作 仓库核心
java·开发语言·数据结构·c++·git·gitee·github
hekung30 分钟前
maven的lifecycle与idea的run
java·maven
阿维的博客日记37 分钟前
为什么 ConcurrentHashMap 采用 synchronized 加锁而不采用ReentrantLock
java·juc
阿丰资源1 小时前
java项目(附资料)-基于SpringBoot+MyBatisPlus+MySQL+Layui的药品管理系统
java·spring boot·mysql
云恒要逆袭1 小时前
Java SE、EE、ME到底啥区别?我被这个问题困扰了一整年
java·java ee
鱼鳞_1 小时前
Java学习笔记_Day27(Stream流)
java·笔记·学习