You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Quarkus框架中实现类似JPA Auditing的功能?

在Quarkus中实现JPA审计功能

如果你想实现类似Spring Data JPA中@CreatedBy/@CreatedDate的审计功能,Quarkus可以通过自定义实体监听器+CDI依赖注入来实现,具体步骤如下:

1. 定义审计基础实体类

创建一个映射超类,包含审计所需的字段,所有需要审计的实体都继承这个类:

@MappedSuperclass
@EntityListeners(AuditEntityListener.class)
public abstract class EntityAuditInfo {

    @Column(name = "created_by", nullable = false)
    private Integer createdBy;

    @Column(name = "created_on", nullable = false)
    private LocalDateTime createdOn;

    @Column(name = "modified_by")
    private Integer modifiedBy;

    @Column(name = "modified_on")
    private LocalDateTime modifiedOn;

    // Getter和Setter方法
    public Integer getCreatedBy() { return createdBy; }
    public void setCreatedBy(Integer createdBy) { this.createdBy = createdBy; }
    public LocalDateTime getCreatedOn() { return createdOn; }
    public void setCreatedOn(LocalDateTime createdOn) { this.createdOn = createdOn; }
    public Integer getModifiedBy() { return modifiedBy; }
    public void setModifiedBy(Integer modifiedBy) { this.modifiedBy = modifiedBy; }
    public LocalDateTime getModifiedOn() { return modifiedOn; }
    public void setModifiedOn(LocalDateTime modifiedOn) { this.modifiedOn = modifiedOn; }
}

2. 实现自定义实体监听器

创建一个CDI管理的实体监听器,利用JPA的@PrePersist和@PreUpdate注解,在实体持久化和更新前自动填充审计字段:

@ApplicationScoped
public class AuditEntityListener {

    @Inject
    CurrentUserService currentUserService;

    @Inject
    Clock clock;

    // 实体首次保存前触发
    @PrePersist
    public void prePersist(EntityAuditInfo entity) {
        Integer currentUserId = currentUserService.getCurrentUserId();
        entity.setCreatedBy(currentUserId);
        entity.setCreatedOn(LocalDateTime.now(clock));
        // 首次保存时同时初始化修改字段
        entity.setModifiedBy(currentUserId);
        entity.setModifiedOn(LocalDateTime.now(clock));
    }

    // 实体更新前触发
    @PreUpdate
    public void preUpdate(EntityAuditInfo entity) {
        Integer currentUserId = currentUserService.getCurrentUserId();
        entity.setModifiedBy(currentUserId);
        entity.setModifiedOn(LocalDateTime.now(clock));
    }
}

3. 实现当前用户获取服务

创建一个CDI bean,用于获取当前登录用户的ID,这里以Quarkus Security为例(如果使用其他认证方式,可自行调整逻辑):

@ApplicationScoped
public class CurrentUserService {

    @Inject
    SecurityIdentity securityIdentity;

    public Integer getCurrentUserId() {
        // 假设当前用户ID存储在SecurityIdentity的Principal名称中,需根据实际认证逻辑调整
        return Integer.valueOf(securityIdentity.getPrincipal().getName());
    }
}

4. 配置依赖(如果需要)

如果使用Quarkus Security,确保添加对应的依赖到pom.xml(Maven)或build.gradle(Gradle):

<!-- Maven -->
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-security</artifactId>
</dependency>

注意事项

  • 时间类型推荐使用LocalDateTime而非Date,更符合Java 8+的日期时间API规范,且Quarkus JPA完全支持。
  • 实体监听器必须被CDI管理(添加@ApplicationScoped),才能正常注入CurrentUserService和Clock。
  • 如果你的认证方式不是Quarkus Security,比如JWT、Session等,只需修改CurrentUserService中的逻辑,从对应的上下文获取用户ID即可。

内容的提问来源于stack exchange,提问作者MightyThor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 10:51:10