hibernate/hibernate-orm · error · MappingException

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

Error message

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

What it means

Plain property lookup failure: getProperty(name, closure) scans the candidate property list for the root segment and throws when no property matches. It is the base resolver behind the public getProperty(String), used whenever mapping code needs a property by exact name on the entity or across its closure. The identifier property is checked separately by the public overload, so this usually means the requested name itself is wrong.

Source

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

			}
		}
		catch ( MappingException e ) {
			throw new MappingException( "property [" + propertyPath + "] not found on entity [" + getEntityName() + "]" );
		}

		return property;
	}

	private Property getProperty(String propertyName, List<Property> properties) throws MappingException {
		final String root = root( propertyName );
		for ( var property : properties ) {
			if ( property.getName().equals( root )
					|| ( property instanceof Backref || property instanceof IndexBackref )
							&& property.getName().equals( propertyName ) ) {
				return property;
			}
		}
		throw new MappingException( "property [" + propertyName + "] not found on entity [" + getEntityName() + "]" );
	}

	@Override
	public Property getProperty(String propertyName) throws MappingException {
		final var identifierProperty = getIdentifierProperty();
		if ( identifierProperty != null
				&& identifierProperty.getName().equals( root( propertyName ) ) ) {
			return identifierProperty;
		}
		else {
			List<Property> closure = getPropertyClosure();
			final var identifierMapper = getIdentifierMapper();
			if ( identifierMapper != null ) {
				closure = new JoinedList<>( identifierMapper.getProperties(), closure );
			}
			return getProperty( propertyName, closure );
		}
	}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Print the available names from getPropertyClosure() and compare with the requested name
  2. Fix the configured name or rename the mapping so both sides agree
  3. For hierarchy-sensitive lookups, resolve against the class that actually declares the property

Example fix

// before
Property p = persistentClass.getProperty("emial");

// after
Property p = persistentClass.getProperty("email");
Defensive patterns

Strategy: validation

Validate before calling

Set<String> available = pc.getPropertyClosure().stream()
        .map(Property::getName)
        .collect(java.util.stream.Collectors.toSet());
if (!available.contains(configuredName)) {
    // do not call getProperty(configuredName); fix the configured name first
}

Prevention

When it happens

Trigger: Calling getProperty with a misspelled or renamed property name; looking up a property that lives on a subclass while holding the root class (or vice versa); custom integrations (filters, tuplizers, mapping tooling) resolving configured property names against the closure.

Common situations: Custom annotation processors or in-house mapping utilities feeding configured names into getProperty; renamed fields after refactors; hierarchy reorganization moving properties between classes.

Related errors


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