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

如何读取标记NOT_AUDITED的关联修改并获取Comment审计数据?

获取关联Comment的Hibernate审计记录

你的场景里,因为给Job.comments标注了@Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED),Hibernate只会审计关联关系的变化(比如添加/删除Comment到Job的操作),而不会审计Comment实体本身,所以生成了JOB_COMMENT_AUD关联审计表,而非COMMENT_AUD。下面两种方法可以帮你获取相关的修改记录:

方法一:通过AuditReader查询Job的修订记录,提取Comment关联变化

既然Job本身是审计的,你可以查询Job的所有修订版本,然后对比不同版本中comments集合的差异,找出哪些Comment被添加或移除了。

示例代码:

// 获取AuditReader实例
AuditReader auditReader = AuditReaderFactory.get(entityManager);
// 获取目标Job的所有修订号
List<Number> revisions = auditReader.getRevisions(Job.class, targetJobId);

// 遍历每个修订版本,提取对应的comments集合
Job previousJob = null;
for (Number rev : revisions) {
    Job currentJob = auditReader.find(Job.class, targetJobId, rev);
    List<Comment> currentComments = currentJob.getComments();
    
    if (previousJob != null) {
        List<Comment> previousComments = previousJob.getComments();
        // 找出新增的Comment:current有但previous没有的
        List<Comment> addedComments = currentComments.stream()
            .filter(c -> !previousComments.contains(c))
            .collect(Collectors.toList());
        // 找出删除的Comment:previous有但current没有的
        List<Comment> removedComments = previousComments.stream()
            .filter(c -> !currentComments.contains(c))
            .collect(Collectors.toList());
        
        // 处理新增/删除记录,比如打印或存储
        System.out.println("修订号 " + rev + " 新增Comment:" + addedComments);
        System.out.println("修订号 " + rev + " 删除Comment:" + removedComments);
    }
    
    previousJob = currentJob;
}

这种方法的优势是不需要额外的实体映射,直接用Hibernate Envers的API操作,但只能获取到关联关系的变化(增删Comment),无法获取Comment内容的修改(不过你提到Comment不可编辑,这刚好符合需求)。

方法二:直接映射并查询JOB_COMMENT_AUD表

Hibernate生成的JOB_COMMENT_AUD表存储了关联关系的审计记录,你可以创建一个实体类直接映射这个表,然后用JPA或原生SQL查询。

步骤1:创建映射实体

@Entity
@Table(name = "JOB_COMMENT_AUD") // 确保表名和Hibernate生成的一致
public class JobCommentAudit {
    @Id
    @Column(name = "rev")
    private Integer revisionId;
    
    @Column(name = "revtype")
    private Integer revisionType;
    // revtype含义:0=新增关联,1=修改关联(你的场景不会出现),2=删除关联
    
    @Column(name = "j_id")
    private Integer jobId;
    
    @Column(name = "id")
    private Integer commentId;

    // Getter和Setter方法
}

步骤2:查询审计记录

用JPA查询:

List<JobCommentAudit> auditRecords = entityManager.createQuery(
        "SELECT jca FROM JobCommentAudit jca WHERE jca.jobId = :jobId",
        JobCommentAudit.class
    )
    .setParameter("jobId", targetJobId)
    .getResultList();

// 遍历处理记录
for (JobCommentAudit record : auditRecords) {
    String action = switch (record.getRevisionType()) {
        case 0 -> "添加了Comment";
        case 2 -> "删除了Comment";
        default -> "未知操作";
    };
    System.out.println("修订号 " + record.getRevisionId() + ":" + action + ",Comment ID:" + record.getCommentId());
    
    // 如果需要Comment的详细信息,可以通过commentId查询Comment表
    Comment comment = entityManager.find(Comment.class, record.getCommentId());
}

或者用原生SQL查询(适合不想创建映射实体的情况):

List<Object[]> rawRecords = entityManager.createNativeQuery(
        "SELECT rev, revtype, j_id, id FROM JOB_COMMENT_AUD WHERE j_id = ?"
    )
    .setParameter(1, targetJobId)
    .getResultList();

for (Object[] record : rawRecords) {
    Integer rev = (Integer) record[0];
    Integer revType = (Integer) record[1];
    Integer jobId = (Integer) record[2];
    Integer commentId = (Integer) record[3];
    // 处理逻辑同上
}

这种方法更直接,能快速获取所有关联操作的审计记录,适合需要批量处理或不需要Job其他审计信息的场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:33:37