hibernate/hibernate-orm · error · HibernateException

Unable to load class {}

Error message

Unable to load class {}

What it means

GroupsPerOperation parses the per-operation validation group settings (jakarta.persistence.validation.group.pre-persist|pre-update|pre-remove, comma-separated class names) and loads each name through Hibernate's ClassLoaderService. A ClassLoadingException for any single group name is rethrown as 'Unable to load class <name>', aborting SessionFactory construction.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/boot/beanvalidation/GroupsPerOperation.java:89

		if ( property instanceof Class<?>[] classes ) {
			return classes;
		}

		if ( property instanceof String string ) {
			final String[] groupNames = split( ",", string );
			if ( groupNames.length == 1 && groupNames[0].isEmpty() ) {
				return EMPTY_GROUPS;
			}

			final List<Class<?>> groupsList = new ArrayList<>( groupNames.length );
			for ( String groupName : groupNames ) {
				final String cleanedGroupName = groupName.trim();
				if ( !cleanedGroupName.isEmpty() ) {
					try {
						groupsList.add( classLoaderAccess.classForName( cleanedGroupName ) );
					}
					catch ( ClassLoadingException e ) {
						throw new HibernateException( "Unable to load class " + cleanedGroupName, e );
					}
				}
			}
			return groupsList.toArray( new Class<?>[0] );
		}

		//null is bad and excluded by instanceof => exception is raised
		throw new HibernateException( JAKARTA_JPA_GROUP_PREFIX
				+ operation.getJakartaGroupPropertyName()
				+ " is of unknown type: String or Class<?>[] only");
	}

	public Class<?>[] get(Operation operation) {
		return groupsPerOperation.get( operation );
	}

	public enum Operation {
		PERSIST( "persist", JPA_GROUP_PREFIX + "pre-persist", JAKARTA_JPA_GROUP_PREFIX + "pre-persist" ),

View on GitHub (pinned to fad1729dce)

Solutions

  1. Fix typos and use the fully-qualified binary name (dots, no .class suffix, no slashes)
  2. Ensure the jar containing the group class is deployed with the app and visible to Hibernate's classloader
  3. After refactors, grep configuration files for stale group FQCNs

Example fix

// before
props.put("jakarta.persistence.validation.group.pre-persist", "com.acme.MyCheck"); // typo / class not deployed

// after
props.put("jakarta.persistence.validation.group.pre-persist", "com.acme.validation.OnPersist");
// and ensure com.acme.validation.OnPersist ships in the deployed jar
Defensive patterns

Strategy: validation

Validate before calling

// resolve every configured group class before building the factory
for (String key : List.of("jakarta.persistence.validation.group.pre-persist",
                          "jakarta.persistence.validation.group.pre-update",
                          "jakarta.persistence.validation.group.pre-remove")) {
    Object v = settings.get(key);
    if (v instanceof String s)
        for (String name : s.split(",")) {
            String cn = name.trim();
            if (!cn.isEmpty())
                Class.forName(cn); // throws early with a clear message if mistyped/not deployed
        }
}

Try / catch

try {
    emf = Persistence.createEntityManagerFactory("pu", settings);
} catch (HibernateException e) {
    if (e.getMessage().startsWith("Unable to load class") && e.getMessage().contains("validation"))
        throw new IllegalStateException("Validation group class missing: " + e.getMessage(), e);
    throw e;
}

Prevention

When it happens

Trigger: Setting e.g. jakarta.persistence.validation.group.pre-persist=com.acme.MyChecks where MyChecks is misspelled, not compiled into the deployed artifact, or invisible to Hibernate's aggregation classloader.

Common situations: The group class lives in another module/jar that is not deployed; refactoring renamed or moved the group class; WAR/EAR classloader visibility rules in application servers hiding the class from Hibernate.

Related errors


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