{"record":{"id":"92a53af9646fab23","repo":"hibernate/hibernate-orm","slug":"unable-to-resolve-mapped-by-path-s-s","errorCode":null,"errorMessage":"Unable to resolve mapped-by path : (%s) %s","messagePattern":"Unable to resolve mapped-by path : \\((.+?)\\) (.+?)","errorType":"exception","errorClass":"MappingException","httpStatus":null,"severity":"critical","filePath":"hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java","lineNumber":672,"sourceCode":"\n\tprivate static AttributeMapping resolveMappedBy(EntityPersister entityPersister, String mappedByProperty) {\n\t\tfinal var propertyPathParts = new StringTokenizer( mappedByProperty, \".\", false );\n\t\tfinal int tokenCount = propertyPathParts.countTokens();\n\t\tassert tokenCount > 0;\n\t\tif ( tokenCount == 1 ) {\n\t\t\treturn entityPersister.findAttributeMapping( propertyPathParts.nextToken() );\n\t\t}\n\t\telse {\n\t\t\tManagedMappingType source = entityPersister;\n\t\t\twhile ( propertyPathParts.hasMoreTokens() ) {\n\t\t\t\tfinal String partName = propertyPathParts.nextToken();\n\t\t\t\tfinal var namedPart = source.findAttributeMapping( partName );\n\t\t\t\tif ( !propertyPathParts.hasMoreTokens() ) {\n\t\t\t\t\treturn namedPart;\n\t\t\t\t}\n\t\t\t\tsource = (ManagedMappingType) namedPart.getPartMappingType();\n\t\t\t}\n\t\t\tthrow new MappingException(\n\t\t\t\t\tString.format(\n\t\t\t\t\t\t\tLocale.ROOT,\n\t\t\t\t\t\t\t\"Unable to resolve mapped-by path : (%s) %s\",\n\t\t\t\t\t\t\tentityPersister.getEntityName(),\n\t\t\t\t\t\t\tmappedByProperty\n\t\t\t\t\t)\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate BeforeExecutionGenerator createGenerator(RuntimeModelCreationContext context, IdentifierCollection collection) {\n\t\tfinal Generator generator =\n\t\t\t\tcollection.getIdentifier()\n\t\t\t\t\t\t.createGenerator( context.getDialect(), null, null, context.getGeneratorSettings() );\n\t\tif ( generator.generatedOnExecution() ) {\n\t\t\tthrow new MappingException(\"must be an BeforeExecutionGenerator\"); //TODO fix message\n\t\t}\n\t\treturn (BeforeExecutionGenerator) generator;","sourceCodeStart":654,"sourceCodeEnd":690,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java#L654-L690","documentation":"AbstractCollectionPersister resolves a mappedBy property path by walking the target entity's attribute mappings token-by-token (source.findAttributeMapping(partName), descending through ManagedMappingType). If a segment is missing or an intermediate segment is not a managed type, resolution fails with MappingException naming the entity and the full mappedBy path.","triggerScenarios":"@OneToMany(mappedBy=\"x\") / @ManyToMany(mappedBy=\"x\") where property x does not exist on the referenced entity; a dotted mappedBy path ('address.city') whose intermediate segment is an embeddable attribute that does not exist or is not embeddable; the path's first token does not match any attribute mapping.","commonSituations":"Rename refactors of the inverse-side property leave mappedBy strings stale; mappedBy copy-pasted from the other side of the association (pointing at itself); dotted paths into @Embedded targets with segments in the wrong order; mappedBy placed on the owning side instead of the inverse side.","solutions":["Verify the mappedBy property exists verbatim on the referenced entity class (check spelling and get/set pairs)","For dotted paths, check each segment: intermediate segments must be embeddable-valued attributes, final segment is the mapped attribute","Ensure mappedBy is on the inverse (non-owning) side and matches the owning side's @JoinColumn/property","After refactors, grep for mappedBy values and keep them in sync with the renamed property"],"exampleFix":"// before\n@Entity public class Order {\n  @OneToMany(mappedBy = \"cust\") // no property 'cust' on Customer\n  private List<OrderLine> lines;\n}\n\n// after\n@Entity public class Order {\n  @OneToMany(mappedBy = \"order\") // exact property on OrderLine\n  private List<OrderLine> lines;\n}","handlingStrategy":"validation","validationCode":"// Verify every mappedBy string resolves on the target entity (supports dotted embeddable paths)\nstatic void checkMappedBy(Class<?> targetEntity, String mappedBy) throws Exception {\n  Class<?> current = targetEntity;\n  String[] parts = mappedBy.split(\"\\\\.\");\n  for (int i = 0; i < parts.length; i++) {\n    java.lang.reflect.Field f = Stream.of(current.getDeclaredFields())\n        .filter(x -> x.getName().equals(parts[i])).findFirst()\n        .orElseThrow(() -> new IllegalStateException(\n            \"mappedBy '\" + mappedBy + \"': no property '\" + parts[i] + \"' on \" + current.getName()));\n    current = f.getType(); // intermediate segments must be embeddable-valued in the real mapping\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  sessionFactory = new Configuration().addAnnotatedClass(Customer.class).buildSessionFactory();\n} catch (MappingException e) {\n  if (e.getMessage() != null && e.getMessage().startsWith(\"Unable to resolve mapped-by path\")) {\n    throw new IllegalStateException(\"A mappedBy value points at a nonexistent property — verify the inverse-side attribute name\", e);\n  }\n  throw e;\n}","preventionTips":["Treat mappedBy strings like API contracts: update them in the same commit as property renames","Keep mappedBy on the inverse side only, referencing the owning side's exact property name","For dotted mappedBy into embeddables, test each segment resolves at startup with the scan above"],"tags":["hibernate","mapped-by","one-to-many","mapping","bootstrap"],"backgroundTag":"invalid-mapped-by","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}