{"record":{"id":"41be5070e59d2887","repo":"hibernate/hibernate-orm","slug":"unable-to-load-class","errorCode":null,"errorMessage":"Unable to load class {}","messagePattern":"Unable to load class (.+?)","errorType":"exception","errorClass":"HibernateException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/boot/beanvalidation/GroupsPerOperation.java","lineNumber":89,"sourceCode":"\t\tif ( property instanceof Class<?>[] classes ) {\n\t\t\treturn classes;\n\t\t}\n\n\t\tif ( property instanceof String string ) {\n\t\t\tfinal String[] groupNames = split( \",\", string );\n\t\t\tif ( groupNames.length == 1 && groupNames[0].isEmpty() ) {\n\t\t\t\treturn EMPTY_GROUPS;\n\t\t\t}\n\n\t\t\tfinal List<Class<?>> groupsList = new ArrayList<>( groupNames.length );\n\t\t\tfor ( String groupName : groupNames ) {\n\t\t\t\tfinal String cleanedGroupName = groupName.trim();\n\t\t\t\tif ( !cleanedGroupName.isEmpty() ) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tgroupsList.add( classLoaderAccess.classForName( cleanedGroupName ) );\n\t\t\t\t\t}\n\t\t\t\t\tcatch ( ClassLoadingException e ) {\n\t\t\t\t\t\tthrow new HibernateException( \"Unable to load class \" + cleanedGroupName, e );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn groupsList.toArray( new Class<?>[0] );\n\t\t}\n\n\t\t//null is bad and excluded by instanceof => exception is raised\n\t\tthrow new HibernateException( JAKARTA_JPA_GROUP_PREFIX\n\t\t\t\t+ operation.getJakartaGroupPropertyName()\n\t\t\t\t+ \" is of unknown type: String or Class<?>[] only\");\n\t}\n\n\tpublic Class<?>[] get(Operation operation) {\n\t\treturn groupsPerOperation.get( operation );\n\t}\n\n\tpublic enum Operation {\n\t\tPERSIST( \"persist\", JPA_GROUP_PREFIX + \"pre-persist\", JAKARTA_JPA_GROUP_PREFIX + \"pre-persist\" ),","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/boot/beanvalidation/GroupsPerOperation.java#L71-L107","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Fix typos and use the fully-qualified binary name (dots, no .class suffix, no slashes)","Ensure the jar containing the group class is deployed with the app and visible to Hibernate's classloader","After refactors, grep configuration files for stale group FQCNs"],"exampleFix":"// before\nprops.put(\"jakarta.persistence.validation.group.pre-persist\", \"com.acme.MyCheck\"); // typo / class not deployed\n\n// after\nprops.put(\"jakarta.persistence.validation.group.pre-persist\", \"com.acme.validation.OnPersist\");\n// and ensure com.acme.validation.OnPersist ships in the deployed jar","handlingStrategy":"validation","validationCode":"// resolve every configured group class before building the factory\nfor (String key : List.of(\"jakarta.persistence.validation.group.pre-persist\",\n                          \"jakarta.persistence.validation.group.pre-update\",\n                          \"jakarta.persistence.validation.group.pre-remove\")) {\n    Object v = settings.get(key);\n    if (v instanceof String s)\n        for (String name : s.split(\",\")) {\n            String cn = name.trim();\n            if (!cn.isEmpty())\n                Class.forName(cn); // throws early with a clear message if mistyped/not deployed\n        }\n}","typeGuard":null,"tryCatchPattern":"try {\n    emf = Persistence.createEntityManagerFactory(\"pu\", settings);\n} catch (HibernateException e) {\n    if (e.getMessage().startsWith(\"Unable to load class\") && e.getMessage().contains(\"validation\"))\n        throw new IllegalStateException(\"Validation group class missing: \" + e.getMessage(), e);\n    throw e;\n}","preventionTips":["Keep group class names in constants shared with config to avoid drift","After renaming/moving group classes, update all persistence unit properties"],"tags":["hibernate","bean-validation","validation-groups","classnotfound","configuration"],"backgroundTag":"class-not-found","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}