{"record":{"id":"f9fd41a1b4547f58","repo":"hibernate/hibernate-orm","slug":"the-changelog-entity-cannot-be-audited","errorCode":null,"errorMessage":"The @Changelog entity cannot be audited","messagePattern":"The @Changelog entity cannot be audited","errorType":"exception","errorClass":"MappingException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/boot/model/internal/AuditHelper.java","lineNumber":410,"sourceCode":"\t\telse {\n\t\t\tfinal String ownerSimpleName = collection.getOwner().getJpaEntityName();\n\t\t\tfinal String childSimpleName = referencedEntity.getJpaEntityName();\n\t\t\treturn ownerSimpleName + \"_\" + childSimpleName + DEFAULT_TABLE_SUFFIX;\n\t\t}\n\t}\n\n\tstatic void bindChangelog(\n\t\t\tChangelog changelog,\n\t\t\tRootClass rootClass,\n\t\t\tClassDetails classDetails,\n\t\t\tMetadataBuildingContext context) {\n\t\tfinal var modelsContext = context.getBootstrapContext().getModelsContext();\n\n\t\t// note : @Changelog currently requires @Entity as well\n\n\t\t// The entity must not be audited\n\t\tif ( classDetails.hasAnnotationUsage( Audited.class, modelsContext ) ) {\n\t\t\tthrow new MappingException( \"The @Changelog entity cannot be audited\" );\n\t\t}\n\n\t\t// Scan class members (including supertypes) for @ChangesetId,\n\t\t// @Timestamp, and @ModifiedEntities. We need the names\n\t\t// and type eagerly to configure the supplier before audit table\n\t\t// second passes create the REV column.\n\t\tMemberDetails revNumberMember = null;\n\t\tMemberDetails revTimestampMember = null;\n\t\tMemberDetails modifiedEntityNamesMember = null;\n\t\tfor ( var current = classDetails; current != null; current = current.getSuperClass() ) {\n\t\t\tfor ( var member : current.getFields() ) {\n\t\t\t\trevNumberMember = checkAnnotation(\n\t\t\t\t\t\tmember,\n\t\t\t\t\t\trevNumberMember,\n\t\t\t\t\t\tChangelog.ChangesetId.class,\n\t\t\t\t\t\tclassDetails\n\t\t\t\t);\n\t\t\t\trevTimestampMember = checkAnnotation(","sourceCodeStart":392,"sourceCodeEnd":428,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/boot/model/internal/AuditHelper.java#L392-L428","documentation":"Hibernate 7's built-in changelog/audit mechanism (org.hibernate.annotations.Changelog) turns the annotated entity into the changeset log that RECORDS audits for other entities; it must therefore never itself be the target of auditing. Binding fails with a MappingException when the @Changelog entity also carries '@Audited'.","triggerScenarios":"A class annotated '@Changelog' (a changeset entity with @Changelog.ChangesetId, @Changelog.Timestamp and optionally @Changelog.ModifiedEntities members) that is also annotated '@Audited'; reusing an old Envers revision entity and adding @Audited 'for consistency'; audit-everything tooling that stamps @Audited on all entities including the changelog.","commonSituations":"Migrating from Envers '@RevisionEntity' to the native @Changelog and leaving @Audited on; team policies that audit all entities automatically; experimenting with the new audit API on an already-audited type.","solutions":["Remove '@Audited' from the @Changelog entity named in the message.","If using global audit-everywhere configuration, exclude the changelog entity from that default.","Verify @Changelog is only on the dedicated changeset entity, not on regular business entities."],"exampleFix":"// before\n@Audited            // -> MappingException\n@Changelog\n@Entity\npublic class Changeset {\n    @Changelog.ChangesetId Long id;\n    @Changelog.Timestamp Instant at;\n}\n\n// after\n@Changelog\n@Entity\npublic class Changeset {\n    @Changelog.ChangesetId Long id;\n    @Changelog.Timestamp Instant at;\n}","handlingStrategy":"validation","validationCode":"// Guard: changelog entities must not be audited\nif (cls.isAnnotationPresent(Changelog.class) && cls.isAnnotationPresent(Audited.class)) {\n    throw new IllegalStateException(\n        cls.getName() + \": @Changelog entity must not be @Audited\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    factory = cfg.buildSessionFactory();\n} catch (MappingException e) {\n    // 'The @Changelog entity cannot be audited' -> remove @Audited from the\n    // changelog entity\n    throw newConfigurationException(\"Changelog misconfiguration\", e);\n}","preventionTips":["Keep exactly one dedicated changelog entity per application, with only @Changelog annotations on it.","If auto-auditing all entities (by annotation scanning), explicitly exclude the changelog class."],"tags":["hibernate","changelog","auditing","orm-mapping"],"backgroundTag":"audit-mapping-error","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}