{"record":{"id":"0e37cbda13486e2f","repo":"hibernate/hibernate-orm","slug":"property-property-is-annotated-optimisticlo-0e37cb","errorCode":null,"errorMessage":"Property '${property}' is annotated '@OptimisticLock(excluded=true)' and '@EmbeddedId'","messagePattern":"Property '(.+?)' is annotated '@OptimisticLock\\(excluded=true\\)' and '@EmbeddedId'","errorType":"exception","errorClass":"AnnotationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/boot/model/internal/PropertyBinder.java","lineNumber":688,"sourceCode":"\t\t\t\t&& !memberDetails.getType().isImplementor( propertyType ) ) {\n\t\t\tthrow new AnnotationException( \"Property '\" + qualify( holder.getPath(), name )\n\t\t\t\t\t+ \"' is annotated '@\" + annotationClass.getSimpleName()\n\t\t\t\t\t+ \"' but is not of type '\" + propertyType.getTypeName() + \"'\" );\n\t\t}\n\t}\n\n\tprivate void validateOptimisticLock(boolean excluded) {\n\t\tif ( excluded ) {\n\t\t\tif ( isVersion( memberDetails ) ) {\n\t\t\t\tthrow new AnnotationException(\"Property '\" + qualify( holder.getPath(), name )\n\t\t\t\t\t\t+ \"' is annotated '@OptimisticLock(excluded=true)' and '@Version'\" );\n\t\t\t}\n\t\t\tif ( isSimpleId( memberDetails ) ) {\n\t\t\t\tthrow new AnnotationException(\"Property '\" + qualify( holder.getPath(), name )\n\t\t\t\t\t\t+ \"' is annotated '@OptimisticLock(excluded=true)' and '@Id'\" );\n\t\t\t}\n\t\t\tif ( isEmbeddedId( memberDetails ) ) {\n\t\t\t\tthrow new AnnotationException( \"Property '\" + qualify( holder.getPath(), name )\n\t\t\t\t\t\t+ \"' is annotated '@OptimisticLock(excluded=true)' and '@EmbeddedId'\" );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * @param elements List of {@link PropertyData} instances\n\t * @param propertyContainer Metadata about a class and its properties\n\t * @param idPropertyCounter number of id properties already present in list of {@link PropertyData} instances\n\t *\n\t * @return total number of id properties found after iterating the elements of {@code annotatedClass}\n\t * using the determined access strategy (starting from the provided {@code idPropertyCounter})\n\t */\n\tstatic int addElementsOfClass(\n\t\t\tList<PropertyData> elements,\n\t\t\tPropertyContainer propertyContainer,\n\t\t\tMetadataBuildingContext context,\n\t\t\tint idPropertyCounter) {","sourceCodeStart":670,"sourceCodeEnd":706,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/boot/model/internal/PropertyBinder.java#L670-L706","documentation":"Same rule as for @Id, but for composite identifiers: an @EmbeddedId property (or the embedded-id aggregate) may not carry @OptimisticLock(excluded = true). Hibernate rejects the combination during property binding because identifier lock participation cannot be toggled with this flag.","triggerScenarios":"A field annotated @EmbeddedId that is additionally annotated @OptimisticLock(excluded = true); commonly happens when templates or IDE refactoring apply the exclusion to all fields of a composite-id entity.","commonSituations":"Composite-key entities generated from templates that add lock exclusions; teams applying excluded=true broadly for performance and catching the id by accident.","solutions":["Remove @OptimisticLock(excluded = true) from the @EmbeddedId property.","Keep excluded=true only on non-id mutable attributes if lock narrowing is really needed."],"exampleFix":"// before\n@EmbeddedId\n@OptimisticLock(excluded = true)\nprivate OrderLineId id;\n\n// after\n@EmbeddedId\nprivate OrderLineId id;","handlingStrategy":"validation","validationCode":"for (Class<?> entity : annotatedClasses) {\n    for (Field f : entity.getDeclaredFields()) {\n        OptimisticLock ol = f.getAnnotation(OptimisticLock.class);\n        if (ol != null && ol.excluded() && f.isAnnotationPresent(EmbeddedId.class)) {\n            throw new IllegalStateException(\"@EmbeddedId property may not use @OptimisticLock(excluded=true): \" + f);\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    SessionFactory sf = cfg.buildSessionFactory();\n} catch (AnnotationException e) {\n    throw new IllegalStateException(\"Optimistic-lock annotation conflict: \" + e.getMessage(), e);\n}","preventionTips":["Treat identifier fields (simple or embedded) as off-limits for @OptimisticLock(excluded=true)"],"tags":["hibernate","jpa","optimistic-lock","embedded-id","annotation-conflict","bootstrap"],"backgroundTag":"optimistic-lock-exclusion-conflict","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}