【随手记录】@MappedSuperclass注解

@MappedSuperclass 是 JPA(Java Persistence API)中的关键注解,用于实现实体类的继承映射。


一、核心作用:创建可重用的映射基类

当多个实体类有相同的字段(如idcreateTimeupdateBy等)时:

// 传统方式:每个实体类重复定义相同字段
@Entity class Order {
    @Id private Long id;
    private LocalDateTime createTime;
    private String createBy;
    // ...其他字段
}

@Entity class Product {
    @Id private Long id;          // 重复字段
    private LocalDateTime createTime; // 重复字段
    private String createBy;      // 重复字段
    // ...其他字段
}

使用 @MappedSuperclass

 
@MappedSuperclass
public abstract class BaseEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    protected Long id;
    
    @Column(name = "create_time")
    private LocalDateTime createTime;
    
    @Column(name = "create_by")
    private String createBy;
}

@Entity
public class Order extends BaseEntity { // 继承公共字段
    private BigDecimal amount;
    // ...无需再定义id/createTime等
}

@Entity
public class Product extends BaseEntity { // 继承公共字段
    private String sku;
    // ...无需再定义id/createTime等
}

二、核心特性详解

1. 非实体(Non-Entity)特性

  • ❌ 不能被 EntityManager 直接查询
    em.find(BaseEntity.class, 1) → 报错

  • ❌ 不能用于 JPQL/HQL 查询
    SELECT b FROM BaseEntity b → 报错

  • ✅ 仅作为字段映射模板供子类使用

2. 字段继承规则

  • ✅ 所有 JPA 注解都会被继承:

    @MappedSuperclass
    public class AuditEntity {
        @Column(name = "updated_at") // 列名映射生效
        private LocalDateTime updatedAt;
    }
    
    @Entity
    public class User extends AuditEntity {
        // 自动拥有 updated_at 字段映射
    }

3. 数据库表结构

  • 子类实体对应的表包含父类所有字段
    User 表结构: 

    user_table (
      id BIGINT PRIMARY KEY,  ← 来自BaseEntity
      create_time DATETIME,   ← 来自BaseEntity
      name VARCHAR(255),      ← User自有字段
      ...
    )

三、与 @Entity 继承的区别

特性@MappedSuperclass@Entity + @Inheritance
是否独立实体 ❌ 否 ✅ 是
是否可被直接查询 ❌ 不能 ✅ 能
数据库表结构 字段合并到子类表中 支持单表/Joined/每类一表
多态查询 ❌ 不支持 ✅ 支持
适用场景 代码复用 (DRY原则) 领域模型的多态关系
posted @ 2025-07-18 15:26  空知大仙人  阅读(76)  评论(0)    收藏  举报