{"record":{"id":"24560583b435837d","repo":"hibernate/hibernate-orm","slug":"no-changelog-configured-this-operation-requires","errorCode":null,"errorMessage":"No @Changelog configured. This operation requires a changelog entity with @Changelog.ChangesetId and @Changelog.Timestamp fields.","messagePattern":"No @Changelog configured\\. This operation requires a changelog entity with @Changelog\\.ChangesetId and @Changelog\\.Timestamp fields\\.","errorType":"exception","errorClass":"AuditException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/audit/internal/AuditLogImpl.java","lineNumber":429,"sourceCode":"\t */\n\tprivate Object resolveTimestampValue(Instant instant) {\n\t\tif ( timestampFieldType == Date.class ) {\n\t\t\treturn Date.from( instant );\n\t\t}\n\t\telse if ( timestampFieldType == LocalDateTime.class ) {\n\t\t\treturn LocalDateTime.ofInstant( instant, ZoneId.systemDefault() );\n\t\t}\n\t\telse if ( timestampFieldType == Instant.class ) {\n\t\t\treturn instant;\n\t\t}\n\t\telse {\n\t\t\treturn instant.toEpochMilli();\n\t\t}\n\t}\n\n\tprivate void requireChangelog() {\n\t\tif ( changelogSupplier == null ) {\n\t\t\tthrow new AuditException(\n\t\t\t\t\t\"No @Changelog configured. \"\n\t\t\t\t\t\t\t+ \"This operation requires a changelog entity with \"\n\t\t\t\t\t\t\t+ \"@Changelog.ChangesetId and @Changelog.Timestamp fields.\"\n\t\t\t);\n\t\t}\n\t}\n\n\t@Override\n\tpublic void close() {\n\t\tif ( auditSession.isOpen() ) {\n\t\t\tauditSession.close();\n\t\t}\n\t}\n\n\tprivate String requireAuditedEntityName(Class<?> entityClass) {\n\t\tfinal var persister = sessionFactory.getMappingMetamodel().getEntityDescriptor( entityClass );\n\t\tif ( persister.getAuditMapping() == null ) {\n\t\t\tthrow new IllegalArgumentException(","sourceCodeStart":411,"sourceCodeEnd":447,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/audit/internal/AuditLogImpl.java#L411-L447","documentation":"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.","triggerScenarios":"Calling any changeset-scoped AuditLog method on a factory bootstrapped without a @Changelog-annotated entity in its persistence unit.","commonSituations":"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.","solutions":["Add a changelog entity annotated @Changelog with @Changelog.ChangesetId and @Changelog.Timestamp properties (see DefaultTrackingModifiedEntitiesChangelog) and include it in the persistence unit.","Until then, restrict usage to per-entity history queries that do not need the changelog.","Verify the changelog entity lives in the same persistence unit as the audited entities."],"exampleFix":"// before - audited entity but no changelog entity registered\n@Audited @Entity class Order { ... }\nauditLog.findChangeset(RevEntity.class, 1L); // AuditException\n// after\n@Changelog @Entity class RevEntity {\n    @Id @GeneratedValue Long id;\n    @Changelog.ChangesetId Long changesetId;\n    @Changelog.Timestamp Instant at;\n}","handlingStrategy":"validation","validationCode":"// startup assertion: a @Changelog entity must be present for changeset APIs\nboolean hasChangelog = persistenceUnitClasses.stream()\n    .anyMatch(c -> c.isAnnotationPresent(Changelog.class));\nif (!hasChangelog) {\n    // restrict the app to per-entity audit queries, or register a changelog entity\n}","typeGuard":null,"tryCatchPattern":"try {\n    auditLog.findChangeset(RevEntity.class, csId);\n}\ncatch (AuditException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"No @Changelog configured\")) {\n        // configure a changelog entity or use changelog-free queries\n    }\n    else throw e;\n}","preventionTips":["Register the changelog entity in the same persistence unit as the audited entities from the start","Add a bootstrap check that fails fast when changeset APIs are wired but no @Changelog entity exists"],"tags":["hibernate","audit","changelog","configuration"],"backgroundTag":"missing-changelog-config","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}