{"record":{"id":"4efff4ef25bff72a","repo":"hibernate/hibernate-orm","slug":"could-not-locate-getter-method-for-property-s-o","errorCode":null,"errorMessage":"Could not locate getter method for property '%s' of class '%s'","messagePattern":"Could not locate getter method for property '(.+?)' of class '(.+?)'","errorType":"exception","errorClass":"PropertyNotFoundException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/internal/util/ReflectHelper.java","lineNumber":467,"sourceCode":"\t\t}\n\n\t\t// check containerClass, and then its super types (if any)\n\t\twhile ( getter == null && checkClass != null ) {\n\t\t\tif ( checkClass.equals( Object.class ) ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tgetter = getGetterOrNull( checkClass, propertyName );\n\t\t\t\t// if no getter found yet, check all implemented interfaces\n\t\t\t\tif ( getter == null ) {\n\t\t\t\t\tgetter = getGetterOrNull( checkClass.getInterfaces(), propertyName );\n\t\t\t\t}\n\t\t\t\tcheckClass = checkClass.getSuperclass();\n\t\t\t}\n\t\t}\n\n\t\tif ( getter == null ) {\n\t\t\tthrow new PropertyNotFoundException(\n\t\t\t\t\tString.format(\n\t\t\t\t\t\t\tLocale.ROOT,\n\t\t\t\t\t\t\t\"Could not locate getter method for property '%s' of class '%s'\",\n\t\t\t\t\t\t\tpropertyName,\n\t\t\t\t\t\t\tcontainerClass.getName()\n\t\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\tensureAccessibility( getter );\n\n\t\treturn getter;\n\t}\n\n\tprivate static Method getGetterOrNull(Class<?>[] interfaces, String propertyName) {\n\t\tMethod getter = null;\n\t\tfor ( int i = 0; getter == null && i < interfaces.length; ++i ) {\n\t\t\tfinal var anInterface = interfaces[i];","sourceCodeStart":449,"sourceCodeEnd":485,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/internal/util/ReflectHelper.java#L449-L485","documentation":"Hibernate resolves mapped properties through JavaBean reflection. ReflectHelper.findGetterMethod walks the class, its superclasses, and all implemented interfaces looking for a public getFoo()/isFoo() accessor whose name matches the mapped property name. When no such method exists anywhere in the hierarchy, it throws PropertyNotFoundException at mapping time, meaning the mapping metadata names a property the Java class does not expose.","triggerScenarios":"Building a SessionFactory where an hbm.xml <property name=\"...\"> or a property-access (@Access(AccessType.PROPERTY)) attribute references a name that has no matching public getter on the class, superclasses, or interfaces. Also produced by direct calls to ReflectHelper.getGetter/findGetterMethod with a property name that has no accessor.","commonSituations":"Typo in the mapped property name versus the actual getter; renaming or removing getters during a refactor while mappings stay stale; non-public or unconventionally named accessors; property access on @Embeddable components without getters; mappings generated from one version of a class while a different version is deployed.","solutions":["Fix the property name in the mapping so it exactly matches an existing getX()/isX() method (case-sensitive, first letter uppercase).","Add the missing public getter to the entity or component class (or one of its superclasses).","Switch the class or property to field access with @Access(AccessType.FIELD) so no getter is required.","If the accessor exists but is non-public or non-standard, make it public or expose a conventional JavaBean getter."],"exampleFix":"// before: mapping expects a getter that does not exist\n@Entity\n@Access(AccessType.PROPERTY)\npublic class User {\n    private String emailAddress;\n    @Column(name = \"email\")\n    public String getEmail() { return emailAddress; } // mapping says \"emial\" -> PropertyNotFoundException\n}\n\n// after: mapping name matches the getter\n@Column(name = \"email\")\npublic String getEmail() { return emailAddress; } // mapped as <property name=\"email\"/>","handlingStrategy":"validation","validationCode":"static void verifyGetters(Class<?> entityClass, List<String> mappedPropertyNames) {\n    java.beans.BeanInfo info;\n    try {\n        info = java.beans.Introspector.getBeanInfo(entityClass);\n    } catch (java.beans.IntrospectionException e) {\n        throw new IllegalStateException(\"Cannot introspect \" + entityClass.getName(), e);\n    }\n    java.util.Set<String> readable = new java.util.HashSet<>();\n    for (java.beans.PropertyDescriptor pd : info.getPropertyDescriptors()) {\n        if (pd.getReadMethod() != null) readable.add(pd.getName());\n    }\n    for (String name : mappedPropertyNames) {\n        if (!readable.contains(name)) {\n            throw new IllegalStateException(\"No getter for mapped property '\" + name + \"' on \" + entityClass.getName());\n        }\n    }\n}","typeGuard":"static boolean hasGetter(Class<?> clazz, String property) {\n    try {\n        return new java.beans.PropertyDescriptor(property, clazz).getReadMethod() != null;\n    } catch (java.beans.IntrospectionException e) {\n        return false;\n    }\n}","tryCatchPattern":"try {\n    SessionFactory sf = metadata.buildSessionFactory();\n} catch (org.hibernate.PropertyNotFoundException e) {\n    // message names the property and class; align the mapping name with a real getter or add the accessor\n}","preventionTips":["Keep mapping property names and Java getters in lockstep; regenerate mappings after renaming fields.","Prefer @Access(AccessType.FIELD) on entity classes without JavaBean accessors.","Add a CI step that builds the SessionFactory so mapping/accessor drift fails the build, not production."],"tags":["hibernate","reflection","mapping","javabean","property-access"],"backgroundTag":"missing-java-bean-getter","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}