hibernate/hibernate-orm · error · MappingException

property [" + propertyPath + "] not found on entity [" + get

Error message

property [" + propertyPath + "] not found on entity [" + getEntityName() + "]

What it means

Thrown when Hibernate fails to resolve a dotted property path against an entity's full property closure. PersistentClass.getRecursiveProperty(path) tokenizes the path on dots and walks the properties, descending into components; if any segment cannot be found, the lookup MappingException is wrapped with this message. It surfaces during binding of references such as property-ref paths that traverse embeddables.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/mapping/PersistentClass.java:557

	 * @throws MappingException If the property could not be found.
	 */
	public Property getReferencedProperty(String propertyPath) throws MappingException {
		try {
			return getRecursiveProperty( propertyPath, getReferenceableProperties() );
		}
		catch ( MappingException e ) {
			throw new MappingException(
					"property-ref [" + propertyPath + "] not found on entity [" + getEntityName() + "]", e
			);
		}
	}

	public Property getRecursiveProperty(String propertyPath) throws MappingException {
		try {
			return getRecursiveProperty( propertyPath, getPropertyClosure() );
		}
		catch ( MappingException e ) {
			throw new MappingException(
					"property [" + propertyPath + "] not found on entity [" + getEntityName() + "]", e
			);
		}
	}

	private Property getRecursiveProperty(String propertyPath, List<Property> properties) throws MappingException {
		Property property = null;
		var tokens = new StringTokenizer( propertyPath, ".", false );
		try {
			while ( tokens.hasMoreElements() ) {
				final String element = (String) tokens.nextElement();
				if ( property == null ) {
					Property identifierProperty = getIdentifierProperty();
					if ( identifierProperty != null && identifierProperty.getName().equals( element ) ) {
						// we have a mapped identifier property and the root of
						// the incoming property path matched that identifier
						// property
						property = identifierProperty;

View on GitHub (pinned to fad1729dce)

Solutions

  1. Check each segment of the path against the mapped property names, starting with the first
  2. Ensure intermediate segments are components (@Embeddable), because the resolver only descends into Component values
  3. Update stale paths in property-ref or key mappings after field renames

Example fix

// before
<many-to-one name="customer" class="Customer" property-ref="homeAddresss.zip"/>

// after
<many-to-one name="customer" class="Customer" property-ref="homeAddress.zip"/>
Defensive patterns

Strategy: validation

Validate before calling

static boolean pathResolvable(PersistentClass pc, String path) {
    Property cur = null;
    var tokens = new java.util.StringTokenizer(path, ".");
    try {
        while (tokens.hasMoreTokens()) {
            String seg = tokens.nextToken();
            cur = (cur == null) ? pc.getProperty(seg)
                                : ((Component) cur.getValue()).getProperty(seg);
        }
        return true;
    }
    catch (Exception e) {
        return false;
    }
}

Prevention

When it happens

Trigger: A dotted path like address.city where address is not a component/embeddable; a typo in any segment of the path; the property exists only on a subclass but the lookup ran against a class whose closure does not include it.

Common situations: Renaming embedded fields; switching an association between embeddable and entity without updating paths; hand-edited XML holding stale paths.

Related errors


AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22). Data as JSON: /api/errors/0b8859818e86fba1. Report an issue: GitHub.