hibernate/hibernate-orm · error · IllegalArgumentException

Entity '<entityName>' is not audited

Error message

Entity '<entityName>' is not audited

What it means

The HQL audit functions modificationType(path) and changesetId(path) must be applied to an audited entity: AuditColumnFunction.convertToSqlAst resolves the path's EntityMappingType and looks up its AuditMapping to find the modification-type / changeset-id column on the root table. If the entity has no audit mapping, there is nothing to select from, so IllegalArgumentException('Entity ... is not audited') is thrown during query translation to SQL AST.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/audit/internal/AuditColumnFunction.java:172

							getArgumentsValidator(),
							getReturnTypeResolver(),
							nodeBuilder(),
							getFunctionName()
					)
			);
		}

		@Override
		public Expression convertToSqlAst(SqmToSqlAstConverter walker) {
			final var entityPath = (SqmPath<?>) getArguments().get( 0 );

			final var tableGroup = walker.getFromClauseAccess()
					.findTableGroup( entityPath.getNavigablePath() );

			final var entityMapping = (EntityMappingType) tableGroup.getModelPart();
			final var auditMapping = entityMapping.getAuditMapping();
			if ( auditMapping == null ) {
				throw new IllegalArgumentException(
						"Entity '" + entityMapping.getEntityName()
								+ "' is not audited"
				);
			}

			// modificationType lives on the root (identifier) table, not subclass tables
			final String originalTable = changesetId
					? entityMapping.getMappedTableDetails().getTableName()
					: entityMapping.getIdentifierTableDetails().getTableName();
			final SelectableMapping selectableMapping = changesetId
					? auditMapping.getChangesetIdMapping( originalTable )
					: auditMapping.getModificationTypeMapping( originalTable );

			final var tableReference = tableGroup.resolveTableReference(
					entityPath.getNavigablePath(),
					originalTable
			);

View on GitHub (pinned to fad1729dce)

Solutions

  1. Annotate the entity with Hibernate's auditing annotation (@Audited) so an audit mapping exists.
  2. If the entity is intentionally unaudited, drop the modificationType()/changesetId() function from that query.
  3. Check the path expression - the function applies to the audited root path, not to an unaudited joined association.

Example fix

// before
List<Object> rows = session
    .createQuery("select modificationType(e) from Document e", Object.class)
    .getResultList(); // Document not audited
// after
@Audited
@Entity
public class Document { ... } // or query an audited entity instead
Defensive patterns

Strategy: validation

Validate before calling

// verify the entity is audited before using audit HQL functions
boolean audited = sessionFactory.getMappingMetamodel()
    .getEntityDescriptor(Document.class)
    .getAuditMapping() != null;
if (!audited) throw new IllegalArgumentException("Document is not audited");

Try / catch

try {
    results = session.createQuery("select modificationType(e) from Document e", Object.class).getResultList();
}
catch (IllegalArgumentException e) {
    if (e.getMessage() != null && e.getMessage().endsWith("is not audited")) {
        // drop the audit function or annotate the entity @Audited
    }
    else throw e;
}

Prevention

When it happens

Trigger: Writing HQL like 'select modificationType(e) from NotAuditedEntity e', or passing an association path that resolves to a non-audited target entity, in a session where the SQM function is converted to SQL.

Common situations: Querying an entity forgotten in the audit configuration; entities intentionally excluded from auditing; copy-pasting a working audit query onto a new entity class.

Related errors


AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22). Data as JSON: /api/errors/529b059ab3dafb06. Report an issue: GitHub.