hibernate/hibernate-orm · error · NoSuchBeanException

Bean class not known to CDI : {}

Error message

Bean class not known to CDI : {}

What it means

ContainerManagedLifecycleStrategy resolves beans from a ready CDI BeanManager via Instance.select(beanType). If that lookup throws (typically UnsatisfiedResolutionException - no resolvable bean of the type), Hibernate wraps it as NoSuchBeanException('Bean class not known to CDI : <fqcn>'). It means CDI is up, but has no bean matching the requested type.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/resource/beans/container/internal/ContainerManagedLifecycleStrategy.java:162

		}

		@Override
		protected Instance<B> resolveContainerInstance() {
			final Instance<Object> root;
			try {
				root = beanManager.createInstance();
			}
			catch (Exception e) {
				// this indicates that the BeanManager is not yet ready to use,
				// which should be considered an error
				throw new NotYetReadyException( e );
			}

			try {
				return root.select( beanType );
			}
			catch (Exception e) {
				throw new NoSuchBeanException( "Bean class not known to CDI : " + beanType.getName(), e );
			}
		}

		@Override
		protected B produceFallbackInstance() {
			return fallbackProducer.produceBeanInstance( beanType );
		}
	}

	private static class NamedBeanImpl<B> extends AbstractBeanImpl<B> {
		private final String beanName;

		private NamedBeanImpl(
				String beanName,
				Class<B> beanType,
				BeanInstanceProducer fallbackProducer,
				BeanManager beanManager) {
			super( beanType, fallbackProducer, beanManager );

View on GitHub (pinned to fad1729dce)

Solutions

  1. Make the class a CDI bean: add a bean-defining annotation (@ApplicationScoped, @Dependent) and ensure the class is public with a usable constructor.
  2. Add META-INF/beans.xml with <bean-discovery-mode>all</bean-discovery-mode> to the jar containing the class.
  3. Remove ambiguity: enable exactly one bean/alternative of that type via @Priority.
  4. Check for @Vetoed on the class or an extensions vetoing it, and remove the veto.

Example fix

// before
public class AuditListener { } // no bean-defining annotation -> not discovered
@Entity @EntityListeners(AuditListener.class)
public class Order { ... }
// -> NoSuchBeanException: Bean class not known to CDI

// after
@ApplicationScoped
public class AuditListener { }
// or add META-INF/beans.xml with bean-discovery-mode=all to that jar
Defensive patterns

Strategy: validation

Validate before calling

// startup self-check: every class Hibernate will resolve as a bean must be resolvable in CDI
@Inject Instance<Object> instance;

void verifyBean(Class<?> required) {
    if (!instance.select(required).isResolvable()) {
        throw new IllegalStateException(required + " is not a resolvable CDI bean");
    }
}

Try / catch

try {
    emf = Persistence.createEntityManagerFactory("pu", props);
} catch (PersistenceException e) {
    if (e.getCause() instanceof org.hibernate.resource.beans.container.spi.NoSuchBeanException nsb) {
        // make the class a CDI bean or add beans.xml, then retry boot
        throw new ConfigurationException(nsb.getMessage(), nsb);
    }
    throw e;
}

Prevention

When it happens

Trigger: Hibernate asks the BeanContainer for a bean by type - an @EntityListeners class, an attribute converter, or a service requested via the managed-bean registry - and CDI cannot resolve it: class not in a bean archive, no bean-defining annotation, class non-public or vetoed, or an ambiguous resolution between alternatives.

Common situations: Entity listeners packaged in a jar without beans.xml under annotated-only discovery; classes missing @ApplicationScoped/@Dependent; Quarkus/Weld SE extensions vetoing beans; deployments split across classloaders so the bean archive is not scanned.

Related errors


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