hibernate/hibernate-orm · error · AuditException

No @Changelog configured. This operation requires a changelo

Error message

No @Changelog configured. This operation requires a changelog entity with @Changelog.ChangesetId and @Changelog.Timestamp fields.

What it means

Changeset-scoped AuditLog operations (getChangesetTimestamp, findChangeset(s), getChangesetId, cross-changeset queries) all need a registered changelog entity, resolved via ChangelogSupplier.resolve from the session factory. When no @Changelog entity exists the supplier is null and requireChangelog() throws AuditException stating that a changelog entity with @Changelog.ChangesetId and @Changelog.Timestamp fields is required.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/audit/internal/AuditLogImpl.java:429

	 */
	private Object resolveTimestampValue(Instant instant) {
		if ( timestampFieldType == Date.class ) {
			return Date.from( instant );
		}
		else if ( timestampFieldType == LocalDateTime.class ) {
			return LocalDateTime.ofInstant( instant, ZoneId.systemDefault() );
		}
		else if ( timestampFieldType == Instant.class ) {
			return instant;
		}
		else {
			return instant.toEpochMilli();
		}
	}

	private void requireChangelog() {
		if ( changelogSupplier == null ) {
			throw new AuditException(
					"No @Changelog configured. "
							+ "This operation requires a changelog entity with "
							+ "@Changelog.ChangesetId and @Changelog.Timestamp fields."
			);
		}
	}

	@Override
	public void close() {
		if ( auditSession.isOpen() ) {
			auditSession.close();
		}
	}

	private String requireAuditedEntityName(Class<?> entityClass) {
		final var persister = sessionFactory.getMappingMetamodel().getEntityDescriptor( entityClass );
		if ( persister.getAuditMapping() == null ) {
			throw new IllegalArgumentException(

View on GitHub (pinned to fad1729dce)

Solutions

  1. Add a changelog entity annotated @Changelog with @Changelog.ChangesetId and @Changelog.Timestamp properties (see DefaultTrackingModifiedEntitiesChangelog) and include it in the persistence unit.
  2. Until then, restrict usage to per-entity history queries that do not need the changelog.
  3. Verify the changelog entity lives in the same persistence unit as the audited entities.

Example fix

// before - audited entity but no changelog entity registered
@Audited @Entity class Order { ... }
auditLog.findChangeset(RevEntity.class, 1L); // AuditException
// after
@Changelog @Entity class RevEntity {
    @Id @GeneratedValue Long id;
    @Changelog.ChangesetId Long changesetId;
    @Changelog.Timestamp Instant at;
}
Defensive patterns

Strategy: validation

Validate before calling

// startup assertion: a @Changelog entity must be present for changeset APIs
boolean hasChangelog = persistenceUnitClasses.stream()
    .anyMatch(c -> c.isAnnotationPresent(Changelog.class));
if (!hasChangelog) {
    // restrict the app to per-entity audit queries, or register a changelog entity
}

Try / catch

try {
    auditLog.findChangeset(RevEntity.class, csId);
}
catch (AuditException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("No @Changelog configured")) {
        // configure a changelog entity or use changelog-free queries
    }
    else throw e;
}

Prevention

When it happens

Trigger: Calling any changeset-scoped AuditLog method on a factory bootstrapped without a @Changelog-annotated entity in its persistence unit.

Common situations: Auditing enabled (@Audited entities) but the changelog entity class forgotten in the entity list; changelog entity present yet missing the @Changelog annotation itself; multi-persistence-unit applications calling the API on the wrong unit.

Related errors


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