hibernate/hibernate-orm · error · HibernateException
jakarta.persistence.validation.group.{} is of unknown type:
Error message
jakarta.persistence.validation.group.{} is of unknown type: String or Class<?>[] only What it means
The value of a jakarta.persistence.validation.group.* property must be either a String (comma-separated class names) or a Class<?>[] / single Class when configuring programmatically. Anything else — List, Set, Properties, Optional — falls through the type checks and hits the final branch, throwing this HibernateException naming the exact property key.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/boot/beanvalidation/GroupsPerOperation.java:97
}
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" ),
MERGE( "merge", JAKARTA_JPA_GROUP_PREFIX + "pre-merge", JAKARTA_JPA_GROUP_PREFIX + "pre-merge" ),
REMOVE( "remove", JPA_GROUP_PREFIX + "pre-remove", JAKARTA_JPA_GROUP_PREFIX + "pre-remove" ),
INSERT( "insert", JAKARTA_JPA_GROUP_PREFIX + "pre-insert", JAKARTA_JPA_GROUP_PREFIX + "pre-insert", true ),
UPDATE( "update", JPA_GROUP_PREFIX + "pre-update", JAKARTA_JPA_GROUP_PREFIX + "pre-update", true ),
UPSERT( "upsert", JAKARTA_JPA_GROUP_PREFIX + "pre-upsert", JAKARTA_JPA_GROUP_PREFIX + "pre-upsert", true ),
DELETE( "delete", JAKARTA_JPA_GROUP_PREFIX + "pre-delete", JAKARTA_JPA_GROUP_PREFIX + "pre-delete" ),
DDL( "ddl", HIBERNATE_GROUP_PREFIX + "ddl", HIBERNATE_GROUP_PREFIX + "ddl", true );
View on GitHub (pinned to fad1729dce)
Solutions
- Pass a single comma-separated String value for the group property
- When configuring programmatically, pass Class<?>[] or a Class instance instead of names
- For Spring Boot YAML, use a scalar string value, not a YAML list
Example fix
// before
Map<String,Object> settings = new HashMap<>();
settings.put("jakarta.persistence.validation.group.pre-persist",
List.of("com.a.G1", "com.b.G2")); // List -> rejected at boot
// after
settings.put("jakarta.persistence.validation.group.pre-persist", "com.a.G1,com.b.G2"); Defensive patterns
Strategy: type-guard
Validate before calling
// normalize the value before it reaches Hibernate
static Object sanitizeGroupValue(Object value) {
if (value instanceof String || value instanceof Class<?>[] || value instanceof Class<?>) return value;
if (value instanceof Collection<?> c)
return c.stream().map(String::valueOf).collect(java.util.stream.Collectors.joining(","));
throw new IllegalArgumentException(
"validation group value must be a comma-separated String or Class<?>[] but was "
+ (value == null ? "null" : value.getClass().getName()));
} Type guard
static boolean isValidGroupSetting(Object value) {
return value instanceof String || value instanceof Class<?>[] || value instanceof Class<?>;
} Try / catch
try {
sessionFactory = configuration.buildSessionFactory();
} catch (HibernateException e) {
if (e.getMessage().contains("is of unknown type: String or Class<?>[] only"))
throw new IllegalStateException("Validation group property must be a String or Class<?>[]", e);
throw e;
} Prevention
- Always configure group properties as scalar strings in YAML/properties files
- Validate the settings map shape in a startup check before SessionFactory construction
When it happens
Trigger: Building a SessionFactory with Map-based settings where a validation group property is bound to a java.util.List (typical when Spring Boot maps a YAML list into jpaProperties) or any non-String, non-Class collection value.
Common situations: Spring Boot application.yml lists bound to map values; configuration DSLs that store collections by default; copying list-style config from other frameworks.
Related errors
- Unable to load class {}
- Given object was not an instance of {} [{}]
- Configuration property hibernate.jdbc.time_zone value [{}] i
- Configuration property hibernate.order_by.default_null_order
- Could not determine how to handle configuration raw [name=${
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/2d1d7f46a5835dea.
Report an issue: GitHub.