hibernate/hibernate-orm · error · MappingException

could not find property [{}] defined in the @Instantiator wi

Error message

could not find property [{}] defined in the @Instantiator withing component [{}]

What it means

Component#isValid reports that a parameter of the @Instantiator-annotated constructor does not correspond to any persistent property of the embeddable. Hibernate binds constructor parameters to properties by name, so every parameter must match a persistent field name exactly.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/mapping/Component.java:825

	public void prepareForMappingModel() {
		// This call will initialize the type properly
		getType();
	}

	@Override
	public boolean isValid(MappingContext mappingContext) throws MappingException {
		if ( !super.isValid( mappingContext ) ) {
			return false;
		}
		if ( instantiatorPropertyNames != null ) {
			if ( instantiatorPropertyNames.length < properties.size() ) {
				throw new MappingException( "component type [" + componentClassName + "] specifies " + instantiatorPropertyNames.length + " properties for the instantiator but has " + properties.size() + " properties" );
			}
			final HashSet<String> assignedPropertyNames = CollectionHelper.setOfSize( properties.size() );
			for ( String instantiatorPropertyName : instantiatorPropertyNames ) {
				if ( getProperty( instantiatorPropertyName ) == null ) {
					throw new MappingException( "could not find property [" + instantiatorPropertyName + "] defined in the @Instantiator withing component [" + componentClassName + "]" );
				}
				assignedPropertyNames.add( instantiatorPropertyName );
			}
			if ( assignedPropertyNames.size() != properties.size() ) {
				final ArrayList<String> missingProperties = new ArrayList<>();
				for ( var property : properties ) {
					final String propertyName = property.getName();
					if ( !assignedPropertyNames.contains( propertyName ) ) {
						missingProperties.add( propertyName );
					}
				}
				throw new MappingException( "component type [" + componentClassName + "] has " + properties.size() + " properties but the instantiator only assigns " + assignedPropertyNames.size() + " properties. missing properties: " + missingProperties );
			}
		}
		return true;
	}

	@Override

View on GitHub (pinned to fad1729dce)

Solutions

  1. Rename the constructor parameter to the exact persistent property name.
  2. Drop parameters that are not persistent properties from the annotated constructor.
  3. Compile with -parameters or use records so parameter names are retained and match fields.

Example fix

// before
@Instantiator
Name(String f, String l) {
    this.first = f;
    this.last = l;
}

// after
@Instantiator
Name(String first, String last) {
    this.first = first;
    this.last = last;
}
Defensive patterns

Strategy: validation

Validate before calling

static List<String> unknownParams(Class<?> embeddable, Constructor<?> ctor) {
    Set<String> fields = Arrays.stream(embeddable.getDeclaredFields())
            .map(Field::getName)
            .collect(Collectors.toSet());
    return Arrays.stream(ctor.getParameters())
            .map(Parameter::getName)
            .filter(n -> !fields.contains(n))
            .toList();
}

Prevention

When it happens

Trigger: Parameter names shortened or abbreviated ('f' for 'first'); a constructor copied from another class; an infrastructure parameter (outer-class reference, flag) added to the annotated constructor; fields renamed without renaming the constructor parameters.

Common situations: Hand-written constructors with compact parameter names; classes compiled without -parameters so parameter names are lost; adding boilerplate parameters to a previously working embeddable.

Related errors


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