Skip to content
Spring Boot sb validation 3 min read

Common Constraints

Jakarta Bean Validation ships a rich set of built-in constraint annotations that cover the vast majority of input rules — required fields, length limits, numeric ranges, formats, and dates. This page is a practical reference: what each annotation does, the types it applies to, and a worked example on a record DTO. All imports come from jakarta.validation.constraints.

Constraints reference

AnnotationApplies toPasses when
@NotNullany typevalue is not null
@NotEmptyString, Collection, Map, arraynot null and size/length > 0
@NotBlankCharSequencenot null and contains at least one non-whitespace char
@Size(min, max)String, Collection, Map, arraylength/size within [min, max]
@Min(v) / @Max(v)integral numbersvalue >= v / <= v
@Positive / @PositiveOrZeronumbersvalue > 0 / >= 0
@Negative / @NegativeOrZeronumbersvalue < 0 / <= 0
@DecimalMin / @DecimalMaxnumbers, Stringwithin a BigDecimal bound
@Digits(integer, fraction)numbers, Stringdigit counts within limits
@EmailCharSequencewell-formed email address
@Pattern(regexp)CharSequencematches the regular expression
@Past / @PastOrPresentdate/time typesin the past / not in the future
@Future / @FutureOrPresentdate/time typesin the future / not in the past
@AssertTrue / @AssertFalsebooleanvalue is true / false

Note: Every constraint (except @NotNull) treats null as valid. @Size, @Email, @Pattern and friends pass on a null value — combine them with @NotNull (or @NotBlank) when the field is also required.

@NotNull vs @NotEmpty vs @NotBlank

These three are the most commonly confused. The distinction matters:

@NotNull   String a;   // rejects null only; "" and "   " are OK
@NotEmpty  String b;   // rejects null and "";        "   " is OK
@NotBlank  String c;   // rejects null, "", and "   " (whitespace-only)
Input@NotNull@NotEmpty@NotBlank
nullfailfailfail
""passfailfail
" "passpassfail
"hi"passpasspass

Use @NotBlank for required text fields, @NotEmpty for required collections, and @NotNull for objects, numbers, and booleans.

A worked example

Here is a realistic registration DTO using a record, combining several constraints:

import jakarta.validation.constraints.*;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.List;

public record RegistrationRequest(

        @NotBlank
        @Size(min = 2, max = 50)
        String fullName,

        @NotBlank
        @Email
        String email,

        @NotBlank
        @Pattern(regexp = "^\\+?[0-9]{7,15}$", message = "invalid phone number")
        String phone,

        @Min(18) @Max(120)
        int age,

        @NotNull
        @Past
        LocalDate dateOfBirth,

        @NotNull
        @PositiveOrZero
        @Digits(integer = 6, fraction = 2)
        BigDecimal accountBalance,

        @NotEmpty
        @Size(max = 5)
        List<@NotBlank String> roles,

        @AssertTrue(message = "you must accept the terms")
        boolean termsAccepted
) {}

A few things worth noting:

  • @Size(max = 50) on fullName caps the length; @Min/@Max bound the numeric age.
  • @Pattern uses a regex — double the backslashes in Java string literals.
  • @Digits(integer = 6, fraction = 2) allows up to six digits before and two after the decimal point.
  • List<@NotBlank String> validates each element of the collection, not just the list itself.
  • Each annotation accepts a message attribute to override the default text.

Custom messages and placeholders

Constraint defaults are usable but generic. Override message, and reference the constraint’s own attributes with {} placeholders:

@Size(min = 8, max = 64, message = "password must be between {min} and {max} characters")
String password;

You can also externalize messages to a ValidationMessages.properties file on the classpath:

# ValidationMessages.properties
user.email.invalid=Please provide a valid email address
@Email(message = "{user.email.invalid}")
String email;

Tip: Keep regular expressions readable. For an email field, prefer @Email over a hand-rolled @Pattern — Hibernate Validator’s implementation handles the tricky edge cases of the address grammar for you.

Composing constraints

Multiple annotations on one field are combined with logical AND — all must pass. Validation does not short-circuit by default, so a single field can report several violations at once (e.g. both @NotBlank and @Size). You can build a reusable composed constraint for common combinations; see Custom Validators.

Last updated June 13, 2026
Was this helpful?