hibernate/hibernate-orm · error · NullServiceException

Unknown service requested [${serviceRole.getName()}]

Error message

Unknown service requested [${serviceRole.getName()}]

What it means

ServiceRegistry.requireService(Class) delegates to getService(role); when the registry has no binding for that role, getService returns null and requireService converts it into NullServiceException, whose message is "Unknown service requested [<role>]". It means the requested service role simply is not registered in this registry instance.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/service/ServiceRegistry.java:69

	/**
	 * Retrieve a service by role, throwing an exception if there is no such service.
	 * If service is not found, but a {@link org.hibernate.service.spi.ServiceInitiator}
	 * is registered for this service role, the service will be initialized and returned.
	 *
	 * @apiNote We cannot return {@code <R extends Service<T>>} here because the service might come from the parent.
	 *
	 * @param serviceRole The service role
	 * @param <R> The service role type
	 *
	 * @return The requested service .
	 *
	 * @throws UnknownServiceException Indicates the service was not known.
	 * @throws NullServiceException Indicates the service was null.
	 */
	default <R extends Service> R requireService(@Nonnull Class<R> serviceRole) {
		final R service = getService( serviceRole );
		if ( service == null ) {
			throw new NullServiceException( serviceRole );
		}
		return service;
	}

	@Override
	void close();
}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Use getService(role) with an explicit null check when the service is optional
  2. Register the role: implement a StandardServiceInitiator/ServiceContributor or call StandardServiceRegistryBuilder.addService()
  3. Request the service from the registry that owns it (e.g. via SessionFactoryImplementor.getServiceRegistry())
  4. Check the registry is still open — a stopped registry no longer resolves services

Example fix

// before
final Dialect dialect = serviceRegistry.requireService(Dialect.class); // not bound at this level

// after
Dialect dialect = serviceRegistry.getService(Dialect.class);
if (dialect == null) {
    // fall back to the registry that owns the service, or register it
    dialect = sessionFactory.getServiceRegistry().requireService(JdbcServices.class).getDialect();
}
Defensive patterns

Strategy: validation

Validate before calling

ConnectionProvider cp = serviceRegistry.getService(ConnectionProvider.class);
if (cp == null) {
    // optional path: register it or fail with a precise message
    throw new IllegalStateException("ConnectionProvider not registered in this registry");
}

Type guard

boolean isServiceAvailable(ServiceRegistry registry, Class<? extends Service> role) {
    return registry.getService(role) != null;
}

Try / catch

try {
    return registry.requireService(role);
}
catch (NullServiceException e) {
    // role not registered in this registry; register it or request from the owning registry
    LOG.warn("service {} unknown to this registry", role.getName());
    return fallbackRegistry().requireService(role);
}

Prevention

When it happens

Trigger: Calling requireService for a role that was never registered via a ServiceInitiator, ServiceContributor, or builder.addService(); asking the wrong registry level (Bootstrap vs Standard vs SessionFactory-owned) for a role owned by another; requesting a service after the registry was stopped.

Common situations: Custom service roles not contributed through META-INF/services ServiceContributor; typos or wrong class passed as role; assuming an optional Hibernate service always exists; accessing SessionFactory-level services before the factory is built.

Related errors


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