{"record":{"id":"f8db75248a6614ad","repo":"hibernate/hibernate-orm","slug":"property-property-is-annotated-optimisticlo","errorCode":null,"errorMessage":"Property '${property}' is annotated '@OptimisticLock(excluded=true)' and '@Version'","messagePattern":"Property '(.+?)' is annotated '@OptimisticLock\\(excluded=true\\)' and '@Version'","errorType":"exception","errorClass":"AnnotationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/boot/model/internal/PropertyBinder.java","lineNumber":680,"sourceCode":"\t\t\tcheckAnnotation( MapKeyColumn.class, Map.class );\n\t\t\tcheckAnnotation( MapKeyJoinColumn.class, Map.class );\n\t\t\tcheckAnnotation( MapKeyJoinColumns.class, Map.class );\n\t\t}\n\t}\n\n\tprivate void checkAnnotation(Class<? extends Annotation> annotationClass, Class<?> propertyType) {\n\t\tif ( memberDetails.hasDirectAnnotationUsage( annotationClass )\n\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 *","sourceCodeStart":662,"sourceCodeEnd":698,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/boot/model/internal/PropertyBinder.java#L662-L698","documentation":"@OptimisticLock(excluded = true) removes a property from the optimistic-locking WHERE clause, which is meaningless (and contradictory) for the @Version property itself — the version is the optimistic lock. PropertyBinder detects the combination during binding and fails fast.","triggerScenarios":"A property annotated with both @Version and @OptimisticLock(excluded = true); usually a stray excluded=true copied from a different field, or an attempt to keep the version column out of update statements.","commonSituations":"Copy-paste of @OptimisticLock(excluded=true) across fields including the version field; misunderstanding the flag as controlling whether the column is written instead of whether it participates in lock checks.","solutions":["Remove @OptimisticLock(excluded = true) from the @Version property.","If the goal was to avoid updating the timestamp on certain operations, use @DynamicUpdate or session-level flush strategies — not lock exclusion."],"exampleFix":"// before\n@Version\n@OptimisticLock(excluded = true)\nprivate LocalDateTime updatedAt;\n\n// after\n@Version\nprivate LocalDateTime updatedAt;","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(Version.class)) {\n            throw new IllegalStateException(\"@Version 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":["Never annotate @Version with @OptimisticLock(excluded=true)","Apply excluded=true selectively to audit/counter fields only"],"tags":["hibernate","jpa","optimistic-lock","version","annotation-conflict","bootstrap"],"backgroundTag":"optimistic-lock-exclusion-conflict","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T14:17:55.899Z"}