hibernate/hibernate-orm · error · IllegalArgumentException

Can't determine field assignment for constructor: {}

Error message

Can't determine field assignment for constructor: {}

What it means

EmbeddableInstantiatorPojoIndirecting.of builds the instantiator used when an embeddable is created via constructor injection (the mapping's resolved instantiator) by matching constructor parameter names to embeddable property names. componentNames is derived from constructor parameter names via reflection; when it is null, name-based assignment is impossible, so Hibernate throws IllegalArgumentException("Can't determine field assignment for constructor: <ctor>") during metamodel building.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/metamodel/internal/EmbeddableInstantiatorPojoIndirecting.java:33

 */
public class EmbeddableInstantiatorPojoIndirecting
		extends AbstractPojoInstantiator
		implements EmbeddableInstantiator {
	protected final Constructor<?> constructor;
	protected final int[] index;

	protected EmbeddableInstantiatorPojoIndirecting(Constructor<?> constructor, int[] index) {
		super( constructor.getDeclaringClass() );
		this.constructor = constructor;
		this.index = index;
	}

	public static EmbeddableInstantiatorPojoIndirecting of(
			String[] propertyNames,
			Constructor<?> constructor,
			String[] componentNames) {
		if ( componentNames == null ) {
			throw new IllegalArgumentException( "Can't determine field assignment for constructor: " + constructor );
		}
		final var index = new int[componentNames.length];
		return EmbeddableHelper.resolveIndex( propertyNames, componentNames, index )
				? new EmbeddableInstantiatorPojoIndirectingWithGap( constructor, index )
				: new EmbeddableInstantiatorPojoIndirecting( constructor, index );
	}

	@Override
	public Object instantiate(ValueAccess valuesAccess) {
		try {
			final var originalValues = valuesAccess.getValues();
			final var values = new Object[originalValues.length];
			for ( int i = 0; i < values.length; i++ ) {
				values[i] = originalValues[index[i]];
			}
			return constructor.newInstance( values );
		}
		catch ( Exception e ) {

View on GitHub (pinned to fad1729dce)

Solutions

  1. Compile with parameter names: Maven — <maven.compiler.parameters>true</maven.compiler.parameters> (or compilerArgument -parameters); Gradle — compileJava { options.compilerArgs << '-parameters' }.
  2. Alternatively provide an explicit custom instantiator with @EmbeddableInstantiator(MyInstantiator.class) or an EmbeddableInstantiatorRegistration so Hibernate does not rely on reflection of parameter names.
  3. Ensure @Embeddable classes are compiled by the same build config (watch out for prebuilt jars / annotation processors like Lombok configuring javac).
  4. Add a canary test that builds the SessionFactory so this surfaces during the build, not at first runtime use.

Example fix

// before (Gradle, no -parameters) — embeddable ctor injection fails
compileJava { }

// after
compileJava {
    options.compilerArgs << '-parameters'
}
Defensive patterns

Strategy: validation

Validate before calling

// build-time guard: fail if embeddable constructors lose parameter names
Constructor<?> c = Address.class.getDeclaredConstructors()[0];
boolean hasNames = !Arrays.stream(c.getParameters()).allMatch(p -> p.isNamePresent() == false);
if (!hasNames) throw new IllegalStateException("Recompile with -parameters for embeddable constructor injection");

Type guard

static boolean parameterNamesAvailable(Class<?> embeddable) {
    return Arrays.stream(embeddable.getDeclaredConstructors())
            .flatMap(c -> Arrays.stream(c.getParameters()))
            .allMatch(Parameter::isNamePresent);
}

Prevention

When it happens

Trigger: An embeddable with constructor injection whose constructor parameter names are unavailable in bytecode — i.e. the classes were compiled without the -parameters javac flag (so reflection returns arg0, arg1... and Hibernate's utility yields null) — triggering EmbeddableInstantiatorPojoIndirecting.of with a null componentNames array.

Common situations: Build systems or CI that don't pass -parameters (Lombok-heavy projects, Gradle defaults in some setups, annotation processors like gradle-incubating, third-party jars containing entities compiled without -parameters); after upgrading to a Hibernate version that started relying on parameter names for embeddable instantiation; IDE-compiled classes used in local runs.

Related errors


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