{"record":{"id":"8c144ab88e989c59","repo":"hibernate/hibernate-orm","slug":"validation-failed-for-classes-during-time-fo","errorCode":null,"errorMessage":"Validation failed for classes {} during {} time for groups [{}]\nList of constraint violations:[\n{}\n]","messagePattern":"Validation failed for classes (.+?) during (.+?) time for groups \\[(.+?)\\]\nList of constraint violations:\\[\n(.+?)\n\\]","errorType":"validation","errorClass":"ConstraintViolationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/boot/beanvalidation/BeanValidationEventListener.java","lineNumber":173,"sourceCode":"\t\t\t\tGroupsPerOperation.Operation.UPDATE\n\t\t);\n\t}\n\n\tprivate <T> void validate(T object, EntityPersister persister, GroupsPerOperation.Operation operation) {\n\t\tif ( object != null && persister.getRepresentationStrategy().getMode() == POJO ) {\n\t\t\tfinal var groups = groupsPerOperation.get( operation );\n\t\t\tif ( groups.length > 0 ) {\n\t\t\t\tfinal var constraintViolations = validator.validate( object, groups );\n\t\t\t\tif ( !constraintViolations.isEmpty() ) {\n\t\t\t\t\tfinal Set<ConstraintViolation<?>> propagatedViolations =\n\t\t\t\t\t\t\tsetOfSize( constraintViolations.size() );\n\t\t\t\t\tfinal Set<String> classNames = new HashSet<>();\n\t\t\t\t\tfor ( var violation : constraintViolations ) {\n\t\t\t\t\t\tBEAN_VALIDATION_LOGGER.trace( violation );\n\t\t\t\t\t\tpropagatedViolations.add( violation );\n\t\t\t\t\t\tclassNames.add( violation.getLeafBean().getClass().getName() );\n\t\t\t\t\t}\n\t\t\t\t\tthrow new ConstraintViolationException(\n\t\t\t\t\t\t\tmessage( operation, classNames, groups, constraintViolations ),\n\t\t\t\t\t\t\tpropagatedViolations );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate <T> String message(\n\t\t\tGroupsPerOperation.Operation operation,\n\t\t\tSet<String> classNames,\n\t\t\tClass<?>[] groups,\n\t\t\tSet<ConstraintViolation<T>> constraintViolations) {\n\t\tfinal var builder = new StringBuilder();\n\t\tbuilder.append( \"Validation failed for classes \" )\n\t\t\t\t.append( classNames )\n\t\t\t\t.append( \" during \" )\n\t\t\t\t.append( operation.getName() )\n\t\t\t\t.append( \" time for groups [\" );","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/boot/beanvalidation/BeanValidationEventListener.java#L155-L191","documentation":"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().","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nem.persist(new User(null, \"jdoe\")); // User.name is @NotNull -> ConstraintViolationException at pre-persist\n\n// after\nem.persist(new User(\"John Doe\", \"jdoe\"));","handlingStrategy":"try-catch","validationCode":"// run the same validation Hibernate would, before touching the EntityManager\nSet<ConstraintViolation<MyEntity>> violations = validator.validate(entity);\nif (!violations.isEmpty()) {\n    throw new IllegalArgumentException(\"Entity invalid: \" + violations);\n}\nem.persist(entity);","typeGuard":null,"tryCatchPattern":"try {\n    em.persist(entity);\n    em.flush();\n} catch (jakarta.validation.ConstraintViolationException e) {\n    Map<String, String> errors = e.getConstraintViolations().stream()\n        .collect(Collectors.toMap(\n            v -> v.getPropertyPath().toString(),\n            ConstraintViolation::getMessage));\n    throw new BadRequestException(errors); // map to a user-facing error; never swallow silently\n}","preventionTips":["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"],"tags":["hibernate","bean-validation","constraint-violation","pre-persist","jakarta-validation"],"backgroundTag":"bean-validation-constraint-violation","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}