
本文介绍一种无需在每个实体类中重复添加 @jsonignore 的通用方案:通过抽象基类集中管理审计字段并自动屏蔽其序列化,兼顾可维护性与代码简洁性。
在 Spring Boot 项目中,启用 JPA 审计(如 @CreatedBy、@CreatedDate)后,审计字段会自动填充数据库,但常因安全或接口规范要求,禁止将其暴露在 REST API 响应中。若为每个实体手动添加 @JsonIgnore 或 @JsonIgnoreProperties,不仅冗余,还易遗漏、难维护——尤其当实体数量庞大时。
推荐采用 “统一抽象基类 + 注解驱动” 的方式实现全局屏蔽:
✅ 核心思路
定义一个 @MappedSuperclass 抽象类(如 AuditedEntity),集中声明所有审计字段,并统一应用 @JsonIgnore;其余业务实体继承该类,即可自动继承审计能力与序列化屏蔽逻辑,零配置、零重复。
✅ 示例实现(Kotlin)
@MappedSuperclass
@EntityListeners(AuditingEntityListener::class)
abstract class AuditedEntity : Serializable {
companion object {
private const val serialVersionUID = 8723456789012345678L
}
@Column(name = "created_at", updatable = false)
@CreationTimestamp
@JsonIgnore
var createdAt: LocalDateTime? = null
@Column(name = "created_by", updatable = false, length = 64)
@CreatedBy
@JsonIgnore
var createdBy: String? = null
@Column(name = "updated_at")
@UpdateTimestamp
@JsonIgnore
var updatedAt: LocalDateTime? = null
@Column(name = "updated_by", length = 64)
@LastModifiedBy
@JsonIgnore
var updatedBy: String? = null
// 可选:提供格式化时间字符串(已自动忽略,仅用于内部逻辑)
val createdAtFormatted: String
get() = createdAt?.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) ?: ""
val updatedAtFormatted: String
get() = updatedAt?.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) ?: ""
}✅ 业务实体只需继承即可
@Entity
@Table(name = "users")
data class User(
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
var id: Long? = null,
@Column(name = "username", nullable = false, unique = true)
var username: String = "",
@Column(name = "email")
var email: String? = null
) : AuditedEntity() // ← 自动拥有审计字段 & 自动 JSON 屏蔽⚠️ 注意事项
- 确保已启用 JPA 审计:在主启动类添加 @EnableJpaAuditing;
- @JsonIgnore 作用于字段级,需配合 Jackson 序列化器(Spring Boot 默认已集成);
- 若需在特定接口中临时启用审计字段(如后台管理 API),可使用 @JsonInclude(JsonInclude.Include.NON_NULL) 配合 DTO 手动映射,避免污染领域模型;
- 时间类型建议统一使用 LocalDateTime(推荐)或 Instant,避免 Date 的时区歧义;
- 如需兼容 Lombok,可在基类上添加 @Data(注意 @EqualsAndHashCode 可能需排除审计字段)。
该方案将横切关注点(审计 + 序列化控制)收敛到单一抽象层,大幅提升代码一致性与可维护性,是大型项目中处理通用元数据字段的推荐实践。










