{"record":{"id":"41adf9f0f8ff572f","repo":"hibernate/hibernate-orm","slug":"entity-entityname-is-not-audited-41adf9","errorCode":null,"errorMessage":"Entity '<entityName>' is not audited","messagePattern":"Entity '<entityName>' is not audited","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/audit/internal/AuditLogImpl.java","lineNumber":447,"sourceCode":"\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(\n\t\t\t\t\t\"Entity '\" + persister.getEntityName() + \"' is not audited\"\n\t\t\t);\n\t\t}\n\t\treturn persister.getEntityName();\n\t}\n\n\tprivate static Instant toInstant(Object value) {\n\t\tif ( value instanceof Instant instant ) {\n\t\t\treturn instant;\n\t\t}\n\t\telse if ( value instanceof LocalDateTime localDateTime ) {\n\t\t\treturn localDateTime.atZone( ZoneId.systemDefault() ).toInstant();\n\t\t}\n\t\telse if ( value instanceof Date date ) {\n\t\t\treturn date.toInstant();\n\t\t}\n\t\telse if ( value instanceof Long millis ) {\n\t\t\treturn Instant.ofEpochMilli( millis );","sourceCodeStart":429,"sourceCodeEnd":465,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/audit/internal/AuditLogImpl.java#L429-L465","documentation":"Every per-entity AuditLog query (getChangesets, getModificationType, find..., getHistory) first resolves the entity descriptor and requires persister.getAuditMapping() != null. For an entity without auditing there are no audit tables to read, so IllegalArgumentException('Entity ... is not audited') is thrown before any query executes.","triggerScenarios":"Passing a non-audited entity class to any AuditLog find/getChangesets/getModificationType method; passing a subclass that is excluded from auditing while only its root is audited (or vice versa).","commonSituations":"Mixed audited/unaudited domain models where audit queries are generic; refactoring that moved classes; intentionally unaudited entities reached through shared code paths.","solutions":["Annotate the entity with @Audited so audit rows are written and it becomes queryable.","If it is intentionally unaudited, guard the call with auditLog.isAudited(entityClass) and query the live entity instead.","For inheritance hierarchies, ensure the concrete subclass you query is audited, not just the root."],"exampleFix":"// before\nList<Object> cs = auditLog.getChangesets(UnauditedThing.class, id);\n// after\nif (auditLog.isAudited(UnauditedThing.class)) {\n    List<Object> cs = auditLog.getChangesets(UnauditedThing.class, id);\n} else {\n    // query the live entity instead\n}","handlingStrategy":"validation","validationCode":"// guard every audit call with the public check\nif (auditLog.isAudited(entityClass)) {\n    List<Object> csIds = auditLog.getChangesets(entityClass, id);\n} else {\n    // entity has no audit mapping: query the live table instead","typeGuard":"static boolean isAuditedEntity(AuditLog auditLog, Class<?> entityClass) {\n    return auditLog.isAudited(entityClass);\n}","tryCatchPattern":"try {\n    List<Object> cs = auditLog.getChangesets(entityClass, id);\n}\ncatch (IllegalArgumentException e) {\n    if (e.getMessage() != null && e.getMessage().endsWith(\"is not audited\")) {\n        // audit the entity or query the live table\n    }\n    else throw e;\n}","preventionTips":["Call auditLog.isAudited(entityClass) before generic audit queries over arbitrary classes","Keep an explicit list of audited entity classes and validate inputs against it"],"tags":["hibernate","audit","entity-mapping","not-audited"],"backgroundTag":"entity-not-audited","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}