hibernate/hibernate-orm · error · StrategySelectionException

Could not instantiate named strategy class [%s]

Error message

Could not instantiate named strategy class [%s]

What it means

For hibernate.type.json_format_mapper or hibernate.type.xml_format_mapper naming a custom FormatMapper class, SessionFactoryOptionsBuilder first tries the constructor taking FormatMapperCreationContext. If that constructor exists but its invocation fails (InvocationTargetException, InstantiationException for abstract classes, or IllegalAccessException for non-public access), a StrategySelectionException is thrown during SessionFactory bootstrap.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/boot/internal/SessionFactoryOptionsBuilder.java:1004

				},
				creationContext
		);
	}

	private static FormatMapper formatMapper(
			Object setting,
			StrategySelector selector,
			Callable<FormatMapper> defaultResolver, FormatMapperCreationContext creationContext) {
		return selector.resolveStrategy( FormatMapper.class, setting, defaultResolver, strategyClass -> {
			try {
				return strategyClass.getDeclaredConstructor( FormatMapperCreationContext.class )
						.newInstance( creationContext );
			}
			catch (NoSuchMethodException e) {
				// Ignore
			}
			catch (InvocationTargetException | InstantiationException | IllegalAccessException e) {
				throw new StrategySelectionException(
						String.format( "Could not instantiate named strategy class [%s]", strategyClass.getName() ),
						e
				);
			}
			try {
				return strategyClass.getDeclaredConstructor().newInstance();
			}
			catch (Exception e) {
				throw new StrategySelectionException(
						String.format( "Could not instantiate named strategy class [%s]", strategyClass.getName() ),
						e
				);
			}
		} );
	}


	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View on GitHub (pinned to fad1729dce)

Solutions

  1. Inspect the nested cause — InvocationTargetException carries the exception your constructor threw
  2. Make the class concrete and the FormatMapperCreationContext constructor public (getDeclaredConstructor is used, but access must still succeed)
  3. Harden ObjectMapper/Jsonb construction: register optional modules defensively, don't throw on unknown settings
  4. If the context constructor is not needed, delete it so Hibernate falls back to the no-arg constructor path

Example fix

// before:
MyFormatMapper(FormatMapperCreationContext ctx) { // package-private + throws
    this.mapper = new ObjectMapper().registerModule(new JavaTimeModule()); // JavaTimeModule not on classpath
}

// after:
public MyFormatMapper(FormatMapperCreationContext ctx) {
    ObjectMapper m = new ObjectMapper();
    if (ClassUtils.isPresent("com.fasterxml.jackson.datatype.jsr310.JavaTimeModule", null)) {
        m.registerModule(new JavaTimeModule());
    }
    this.mapper = m;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// if you register a custom FormatMapper, check its constructors beforehand
Class<?> c = Class.forName(props.getProperty("hibernate.type.json_format_mapper"));
boolean ctxCtor = Arrays.stream(c.getDeclaredConstructors())
    .anyMatch(ct -> ct.getParameterCount() == 1
                && ct.getParameterTypes()[0] == FormatMapperCreationContext.class
                && Modifier.isPublic(ct.getModifiers()));
boolean noArg = Arrays.stream(c.getDeclaredConstructors())
    .anyMatch(ct -> ct.getParameterCount() == 0 && Modifier.isPublic(ct.getModifiers()));
if (!ctxCtor && !noArg) throw new IllegalStateException("FormatMapper needs a usable constructor");

Try / catch

try {
    sessionFactory = metadata.buildSessionFactory();
} catch (StrategySelectionException e) {
    if (e.getMessage() != null && e.getMessage().contains("Could not instantiate named strategy class")) {
        Throwable root = e.getCause();
        while (root != null && root.getCause() != null) root = root.getCause();
        log.error("FormatMapper construction failed: {}", root, e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Setting hibernate.type.json_format_mapper=com.acme.MyFormatMapper where MyFormatMapper has a FormatMapperCreationContext constructor that is not public, the class is abstract, or the constructor body throws (e.g. failing to build an ObjectMapper).

Common situations: Custom Jackson/Yasson wrapper whose constructor configures an ObjectMapper that fails (module missing); constructor left package-private; subclassing a shipped FormatMapper but keeping it abstract by mistake; the context passed in being used before it is fully initialized.

Related errors


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