{"record":{"id":"e524f1b6c20af761","repo":"theonedev/onedev","slug":"getter-not-found-for-property-propertyname","errorCode":null,"errorMessage":"Getter not found for property: ${propertyName}","messagePattern":"Getter not found for property: (.+?)","errorType":"validation","errorClass":"ExplicitException","httpStatus":null,"severity":"error","filePath":"server-core/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java","lineNumber":1350,"sourceCode":"\t}\n\n\tprivate boolean isValidationRequired(BaseBeanValidationContext<?> validationContext,\n\t\t\tValueContext<?, ?> valueContext,\n\t\t\tMetaConstraint<?> metaConstraint) {\n\t\tvar location = metaConstraint.getLocation();\n\t\tif (location instanceof TypeArgumentConstraintLocation) {\n\t\t\tlocation = ((TypeArgumentConstraintLocation) location).getOuterDelegate();\n\t\t}\t\t\n\t\tif (location instanceof AbstractPropertyConstraintLocation && valueContext.getCurrentBean() != null) {\n\t\t\t// Check if this constraint comes from a superclass method that has been overridden\n\t\t\tif (isConstraintFromOverriddenMethod(location, valueContext.getCurrentBean().getClass(), metaConstraint.getDescriptor().getAnnotationType())) {\n\t\t\t\treturn false; // Skip validation for constraints from overridden superclass methods\n\t\t\t}\n\t\t\tvar bean = valueContext.getCurrentBean();\t\t\t\n\t\t\tvar propertyName = ((AbstractPropertyConstraintLocation<?>) location).getPropertyName();\n\t\t\tvar getter = BeanUtils.findGetter(bean.getClass(), propertyName);\n\t\t\tif (getter == null) {\n\t\t\t\tthrow new ExplicitException(\"Getter not found for property: \" + propertyName);\n\t\t\t}\n\t\t\tfor (var dependsOn : getter.getAnnotationsByType(DependsOn.class)) {\n\t\t\t\tvar dependencyGetter = BeanUtils.findGetter(bean.getClass(), dependsOn.property());\n\t\t\t\tif (dependencyGetter == null) {\n\t\t\t\t\tthrow new ExplicitException(\"Getter not found for property: \" + dependsOn.property());\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tvar dependencyPropertyValue = dependencyGetter.invoke(bean);\n\t\t\t\t\tif (!DependsOnUtils.isPropertyVisible(dependsOn, dependencyGetter.getReturnType(), dependencyPropertyValue))\n\t\t\t\t\t\treturn false;\n\t\t\t\t} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {\n\t\t\t\t\tthrow new ExplicitException(\"Error invoking getter for property: \" + dependsOn.property(), e);\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar showCondition = getter.getAnnotation(ShowCondition.class);\n\t\t\tif (showCondition != null) {\n\t\t\t\tEditContext.push(new EditContext() {\n\t\t\t\t\t@Override","sourceCodeStart":1332,"sourceCodeEnd":1368,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java#L1332-L1368","documentation":"OneDev-specific extension in ValidatorImpl: when validating a property constraint whose location is an AbstractPropertyConstraintLocation, it looks up the property's getter via BeanUtils.findGetter on the current bean's class; if no getter exists it throws ExplicitException. Hibernate's own validation only needs the field, but OneDev's DependsOn/ShowCondition machinery requires an actual callable getter.","triggerScenarios":"Declaring a constraint on a property that only has a field with no corresponding getter (getX/isX or fluent name()), or a getter named inconsistently with the property name in the constraint location.","commonSituations":"Custom editable/input property definitions in OneDev where a property was added without its getter, renamed getters, or boolean fields using 'get' prefix instead of 'is'.","solutions":["Add the missing getter to the bean class (matching JavaBeans naming for the property).","Fix the property name used in the constraint/property location to match an existing getter.","If the property should not expose a getter, move the constraint to a property that has one."],"exampleFix":"// before\nclass Settings {\n    private String url;\n    @NotEmpty\n    private String name; // no getter\n}\n\n// after\nclass Settings {\n    private String url;\n    private String name;\n    @NotEmpty\n    public String getName() { return name; }\n}","handlingStrategy":"type-guard","validationCode":"// fail fast in tests if constrained properties lack getters\nfor (String prop : constrainedProperties) {\n    if (BeanUtils.findGetter(beanClass, prop) == null)\n        throw new IllegalStateException(\"missing getter for \" + prop);\n}","typeGuard":"static boolean hasGetter(Class<?> type, String property) {\n    String cap = Character.toUpperCase(property.charAt(0)) + property.substring(1);\n    try {\n        type.getMethod(\"get\" + cap);\n        return true;\n    } catch (NoSuchMethodException e) {\n        try { type.getMethod(\"is\" + cap); return true; }\n        catch (NoSuchMethodException e2) { return false; }\n    }\n}","tryCatchPattern":"try {\n    validator.validate(bean);\n} catch (Exception e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"Getter not found for property: \")) {\n        // add the getter or fix the property name\n    } else throw e;\n}","preventionTips":["Always give constrained properties a standard JavaBeans getter.","Keep property names in constraint locations in sync with getter names.","Add a unit test that resolves getters for every constrained property."],"tags":["validation","reflection","javabeans","onedev"],"backgroundTag":"getter-not-found","analyzedSha":"d44925c47c37992c828ea673a5f9620539bc3ff2","analyzedAt":"2026-09-06T07:18:27.995Z","contentChangedAt":"2026-09-06T07:18:27.995Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}