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

}
相关推荐
代码之光_19806 分钟前
保障性住房管理:SpringBoot技术优势分析
java·spring boot·后端
ajsbxi11 分钟前
苍穹外卖学习记录
java·笔记·后端·学习·nginx·spring·servlet
StayInLove30 分钟前
G1垃圾回收器日志详解
java·开发语言
对许34 分钟前
SLF4J: Failed to load class “org.slf4j.impl.StaticLoggerBinder“
java·log4j
鹿屿二向箔35 分钟前
基于SSM(Spring + Spring MVC + MyBatis)框架的咖啡馆管理系统
spring·mvc·mybatis
无尽的大道38 分钟前
Java字符串深度解析:String的实现、常量池与性能优化
java·开发语言·性能优化
小鑫记得努力1 小时前
Java类和对象(下篇)
java
binishuaio1 小时前
Java 第11天 (git版本控制器基础用法)
java·开发语言·git
zz.YE1 小时前
【Java SE】StringBuffer
java·开发语言
老友@1 小时前
aspose如何获取PPT放映页“切换”的“持续时间”值
java·powerpoint·aspose