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

删除@OneToMany关联父实体时Hibernate Envers向子审计表插入空ID

解决Hibernate Envers删除Batch时插入空ID到审计表的问题

问题核心原因是BatchTechnicalRecord实体对中间表的双重映射:你既通过@OneToMany + @JoinTable让Hibernate自动管理batch_technical_record_attachment表,又手动创建了BatchTechnicalRecordAttachment实体映射同一张表。这种冲突导致Envers在处理级联删除的审计日志时,无法正确获取中间表记录的ID,触发空值约束错误。

解决方案步骤

1. 替换BatchTechnicalRecord的关联配置

删除BatchTechnicalRecord中自动管理中间表的@OneToMany + @JoinTable代码,改为关联手动定义的中间表实体:

@Audited
@Entity
@Table(name = "batch_technical_record")
public class BatchTechnicalRecord extends BaseEntity implements Serializable {

    // 替换原attachments关联,改为关联中间表实体
    @OneToMany(mappedBy = "batchTechnicalRecord", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
    private List<BatchTechnicalRecordAttachment> attachmentRelations;
    ...
}

2. 修正BatchTechnicalRecordAttachment的关联配置

确认中间表实体的关联配置无误,同时修正原foreignKey名称的重复错误:

@Audited
@Entity
@Table(name = "batch_technical_record_attachment")
public class BatchTechnicalRecordAttachment extends BaseEntity implements Serializable {

    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinColumn(name = "id_attachment", referencedColumnName = "id", nullable = false, foreignKey = @ForeignKey(name = "fk_batch_technical_record_attachment_attachment"))
    private Attachment attachment;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "id_batch_technical_record", referencedColumnName = "id", nullable = false, foreignKey = @ForeignKey(name = "fk_batch_technical_record_attachment_batch_technical_record"))
    private BatchTechnicalRecord batchTechnicalRecord;
    ...
}

3. 调整业务代码的关联操作

如果之前直接操作BatchTechnicalRecord.attachments,现在需要改为通过中间实体关联Attachment:

// 示例:添加Attachment到BatchTechnicalRecord
BatchTechnicalRecord record = ...;
Attachment attachment = ...;

BatchTechnicalRecordAttachment relation = new BatchTechnicalRecordAttachment();
relation.setBatchTechnicalRecord(record);
relation.setAttachment(attachment);

record.getAttachmentRelations().add(relation);

4. 验证审计表结构

确保batch_technical_record_attachment_aud表的id字段非空约束正常,且ID生成策略与主表(继承自BaseEntity)一致。

原理说明

同时使用自动生成的中间表关联和手动实体映射时,Hibernate Envers无法正确跟踪中间表的变更逻辑:两种关联方式的审计规则冲突,导致删除操作时Envers无法获取中间表实体的ID,最终触发空值插入错误。统一使用实体类管理中间表后,Envers能正常跟踪其生命周期,正确生成审计日志。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 21:15:36