hibernate/hibernate-orm · error · MappingException
No audit mapping available for
Error message
No audit mapping available for %s
What it means
EntityAuditSupport wraps an entity persister for Hibernate's built-in auditing / changeset coordination. Its constructor requires entityPersister.getAuditMapping() to be non-null; MappingException 'No audit mapping available for <entity>' means audit support was constructed for an entity whose mapping never configured auditing. The failure happens while wiring audit support, not while reading or writing audit data.
Solutions
- Add the audit mapping to the entity using the auditing configuration your Hibernate version provides (e.g. the audit annotation on the entity)
- Apply it to the whole hierarchy - subclass persisters are constructed from the root configuration
- Audit-check every entity type your code calls audit/changeset APIs for before enabling the coordinator
- If auditing is optional for some entities, guard call sites so audit APIs are only used for audited types
Defensive patterns
Strategy: validation
Validate before calling
// before enabling the audit coordinator: every audited-API target must have an audit mapping
EntityPersister p = factory.getRuntimeMetamodels().getMappingMetamodel()
.getEntityDescriptor(entityName);
if (p.getAuditMapping() == null) {
throw new IllegalArgumentException("Entity not configured for auditing: " + entityName);
} Try / catch
try { auditApi.forEntity(entityName); } catch (MappingException e) { if (e.getMessage().contains("No audit mapping")) { /* skip or configure auditing for this entity */ } } Prevention
- Annotate whole hierarchies, not isolated classes, when enabling auditing
- Keep a list of audited entity names and check membership before calling audit APIs
- Validate audit coverage in a SessionFactory bootstrap test
When it happens
Trigger: Enabling the audit/changeset coordinator and then requesting audit services for an entity that lacks the audit mapping - e.g. only some classes of a hierarchy (or only some entities of the unit of work) are annotated for auditing; programmatic mappings that skip audit configuration; code asking for audit state of an un-audited entity type.
Common situations: Rolling out auditing per-entity and missing the hierarchy root or one subclass; mixing Envers-style annotations with the built-in coordinator; config that assumes global auditing while the mapping enables it per class.
Related errors
- discriminator mapping required for single table polymorphic…
- Encountered 'subclass table index
- Unable to resolve audit table mapping for
- Ambiguous persistent property methods declared by
- An association from the table '" + getTable().getName() +…
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/82cc886c904a8c23.
Report an issue: GitHub.
Appendix: source
Thrown at hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/EntityAuditSupport.java:122
private final EntityPersister entityPersister;
private final SessionFactoryImplementor factory;
private final AuditMapping auditMapping;
private final EntityTableMapping[] auditTableMappings;
private final boolean[] auditedPropertyMask;
private final boolean useServerTransactionTimestamps;
private final String currentTimestampFunctionName;
private final MutationGroup staticAuditInsertMutationGroup;
private final MutationGroup transactionEndUpdateMutationGroup;
public EntityAuditSupport(
EntityPersister entityPersister,
SessionFactoryImplementor factory) {
this.entityPersister = entityPersister;
this.factory = factory;
this.auditMapping = entityPersister.getAuditMapping();
if ( auditMapping == null ) {
throw new MappingException( "No audit mapping available for " + entityPersister.getEntityName() );
}
this.auditTableMappings = buildAuditTableMappings();
this.auditedPropertyMask = new boolean[entityPersister.getPropertySpan()];
for ( int i = 0; i < auditedPropertyMask.length; i++ ) {
auditedPropertyMask[i] = !entityPersister.isPropertyAuditedExcluded( i );
}
this.useServerTransactionTimestamps =
factory.getChangesetCoordinator().useServerTimestamp( factory.getJdbcServices().getDialect() );
this.currentTimestampFunctionName = useServerTransactionTimestamps
? factory.getJdbcServices().getDialect().currentTimestamp()
: null;
this.staticAuditInsertMutationGroup = entityPersister.isDynamicInsert()
? null
: buildAuditInsertMutationGroup( applyAuditMask( entityPersister.getPropertyInsertability() ), null, null );
this.transactionEndUpdateMutationGroup = buildTransactionEndUpdateMutationGroup();
}
public EntityPersister getEntityPersister() {View on GitHub (pinned to fad1729dce)