hibernate/hibernate-orm · error · ConstraintViolationException
Validation failed for classes {} during {} time for groups [
Error message
Validation failed for classes {} during {} time for groups [{}]
List of constraint violations:[
{}
] What it means
BeanValidationEventListener runs Jakarta Validation before each pre-persist/pre-update/pre-remove entity event, using the groups configured per operation (jakarta.persistence.validation.group.pre-*). When the Validator returns any violation, Hibernate throws jakarta.validation.ConstraintViolationException whose message lists the failing classes, the operation, the groups, and each violation; the full violation set is available via getConstraintViolations().
Source
Thrown at hibernate-core/src/main/java/org/hibernate/boot/beanvalidation/BeanValidationEventListener.java:173
GroupsPerOperation.Operation.UPDATE
);
}
private <T> void validate(T object, EntityPersister persister, GroupsPerOperation.Operation operation) {
if ( object != null && persister.getRepresentationStrategy().getMode() == POJO ) {
final var groups = groupsPerOperation.get( operation );
if ( groups.length > 0 ) {
final var constraintViolations = validator.validate( object, groups );
if ( !constraintViolations.isEmpty() ) {
final Set<ConstraintViolation<?>> propagatedViolations =
setOfSize( constraintViolations.size() );
final Set<String> classNames = new HashSet<>();
for ( var violation : constraintViolations ) {
BEAN_VALIDATION_LOGGER.trace( violation );
propagatedViolations.add( violation );
classNames.add( violation.getLeafBean().getClass().getName() );
}
throw new ConstraintViolationException(
message( operation, classNames, groups, constraintViolations ),
propagatedViolations );
}
}
}
}
private <T> String message(
GroupsPerOperation.Operation operation,
Set<String> classNames,
Class<?>[] groups,
Set<ConstraintViolation<T>> constraintViolations) {
final var builder = new StringBuilder();
builder.append( "Validation failed for classes " )
.append( classNames )
.append( " during " )
.append( operation.getName() )
.append( " time for groups [" );View on GitHub (pinned to fad1729dce)
Solutions
- Inspect e.getConstraintViolations() and fix the offending property values before saving
- Adjust the constraint (or move it to a different validation group) if the rule itself is wrong
- If the field is legitimately optional at this lifecycle stage, validate it in a later-phase group instead of the default one
- As a last resort set validation-mode NONE or jakarta.persistence.validation.mode=none — but never in production just to hide data bugs
Example fix
// before
em.persist(new User(null, "jdoe")); // User.name is @NotNull -> ConstraintViolationException at pre-persist
// after
em.persist(new User("John Doe", "jdoe")); Defensive patterns
Strategy: try-catch
Validate before calling
// run the same validation Hibernate would, before touching the EntityManager
Set<ConstraintViolation<MyEntity>> violations = validator.validate(entity);
if (!violations.isEmpty()) {
throw new IllegalArgumentException("Entity invalid: " + violations);
}
em.persist(entity); Try / catch
try {
em.persist(entity);
em.flush();
} catch (jakarta.validation.ConstraintViolationException e) {
Map<String, String> errors = e.getConstraintViolations().stream()
.collect(Collectors.toMap(
v -> v.getPropertyPath().toString(),
ConstraintViolation::getMessage));
throw new BadRequestException(errors); // map to a user-facing error; never swallow silently
} Prevention
- Validate at the API/service boundary with the same groups the entity uses
- Keep bean constraints in sync with API-level validation rules
- Cover persist/update/remove paths with validation-asserting tests
When it happens
Trigger: Calling persist()/merge()/remove() (including cascades) on an entity whose state violates its constraints — a @NotNull field set to null, @Size/@Pattern violated, @Min/@Max out of range — while the SessionFactory runs with validation mode CALLBACK (the Jakarta default) or AUTO with a provider present.
Common situations: Saving partially populated objects mapped as entities; frontend or batch jobs bypassing the API layer's validation; a constraint tightened later (field newly @NotNull) while existing data flows still send null; @Valid cascades revealing violations on embedded objects.
Related errors
- Unable to check validity of passed ValidatorFactory
- Unable to locate TypeSafeActivator#activate method
- Error activating Bean Validation integration
- Jakarta Validation API was not available, but 'callback' val
- Bean Validation API was not available, but 'hibernate.toolin
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/8c144ab88e989c59.
Report an issue: GitHub.