Repository navigation
Metadata
The Jakarta Validation metadata API describes what is constrained, without validating anything. Its root is
Validator.getConstraintsForClass(Class), a BeanDescriptor. Every descriptor type has an entry point and an
assertion, and the assertions navigate from one descriptor to the next.
| Descriptor | Entry point | Assertion |
|---|---|---|
BeanDescriptor |
assertThatBeanDescriptor |
AbstractBeanDescriptorAssert<?> |
PropertyDescriptor |
assertThatPropertyDescriptor |
AbstractPropertyDescriptorAssert<?> |
MethodDescriptor |
assertThatMethodDescriptor |
AbstractMethodDescriptorAssert<?> |
ConstructorDescriptor |
assertThatConstructorDescriptor |
AbstractConstructorDescriptorAssert<?> |
ParameterDescriptor |
assertThatParameterDescriptor |
AbstractParameterDescriptorAssert<?> |
ReturnValueDescriptor |
assertThatReturnValueDescriptor |
AbstractReturnValueDescriptorAssert<?> |
CrossParameterDescriptor |
assertThatCrossParameterDescriptor |
AbstractCrossParameterDescriptorAssert<?> |
ContainerElementTypeDescriptor |
assertThatContainerElementTypeDescriptor |
AbstractContainerElementTypeDescriptorAssert<?> |
GroupConversionDescriptor |
assertThatGroupConversionDescriptor |
AbstractGroupConversionDescriptorAssert<?> |
ConstraintDescriptor<T> |
assertThatConstraintDescriptor |
AbstractConstraintDescriptorAssert<?, ?, T> |
The assertion classes follow the descriptor interfaces:
AbstractElementDescriptorAssert hasConstraints, elementClass, constraintDescriptors
├── AbstractBeanDescriptorAssert
├── AbstractExecutableDescriptorAssert name, parameters, cross parameter, return value
│ ├── AbstractMethodDescriptorAssert
│ └── AbstractConstructorDescriptorAssert
├── AbstractCrossParameterDescriptorAssert
└── AbstractCascadableContainerDescriptorAssert cascaded, group conversions, container element types
├── AbstractPropertyDescriptorAssert
├── AbstractParameterDescriptorAssert
├── AbstractReturnValueDescriptorAssert
└── AbstractContainerElementTypeDescriptorAssert
AbstractGroupConversionDescriptorAssert (not an ElementDescriptor)
AbstractConstraintDescriptorAssert (not an ElementDescriptor)
ElementDescriptor, CascadableDescriptor and ContainerDescriptor always occur together on property, parameter,
return-value and container-element-type descriptors, so one intersection-bounded class covers them.
| Method | |
|---|---|
hasConstraints(), doesNotHaveConstraints(), extractingHasConstraints()
|
ElementDescriptor.hasConstraints() |
hasElementClass(Class), extractingElementClass()
|
getElementClass() |
extractingConstraintDescriptors() |
getConstraintDescriptors(), as a CollectionAssert<ConstraintDescriptor<?>>
|
extractingConstraintDescriptors(UnaryOperator<ConstraintFinder>) |
findConstraints(), configured by the operator, then getConstraintDescriptors()
|
| Method | |
|---|---|
isBeanConstrained(), isNotBeanConstrained(), extractingBeanConstrained()
|
isBeanConstrained() |
extractingConstraintsForProperty(String) |
a property-descriptor assertion; its actual is null when the property is neither constrained nor cascaded |
hasConstraintsForProperty(String) |
the above is not null
|
extractingConstrainedProperties() |
CollectionAssert<PropertyDescriptor> |
extractingConstraintsForMethod(String name, Class<?>... parameterTypes) |
a method-descriptor assertion; actual is null when the method is unconstrained |
extractingConstrainedMethods(MethodType, MethodType...) |
CollectionAssert<MethodDescriptor> |
extractingConstraintsForConstructor(Class<?>... parameterTypes) |
a constructor-descriptor assertion |
extractingConstrainedConstructors() |
CollectionAssert<ConstructorDescriptor> |
The extractingConstraintsFor… methods also have overloads taking an AssertFactory — first for the method and
constructor forms, after the name for the property form.
assertThatBeanDescriptor(validator.getConstraintsForClass(Greeter.class))
.isBeanConstrained()
.hasElementClass(Greeter.class)
.hasConstraintsForProperty("name")
.extractingConstraintsForProperty("name")
.hasPropertyName("name")
.hasConstraints()
.isNotCascaded();
assertThatBeanDescriptor(validator.getConstraintsForClass(Greeter.class))
.extractingConstraintsForProperty("nosuch")
.isNull();AbstractExecutableDescriptorAssert, shared by the method and constructor descriptor assertions:
| Method | |
|---|---|
hasName(String), extractingName()
|
getName() |
extractingParameterDescriptors() |
ListAssert<ParameterDescriptor> |
extractingParameterDescriptor(int), extractingParameterDescriptor(int, AssertFactory)
|
the parameter at an index; see the index contract below |
hasConstrainedParameters(), doesNotHaveConstrainedParameters(), extractingHasConstrainedParameters()
|
|
hasConstrainedReturnValue(), doesNotHaveConstrainedReturnValue(), extractingHasConstrainedReturnValue()
|
|
extractingCrossParameterDescriptor(), extractingCrossParameterDescriptor(AssertFactory)
|
|
extractingReturnValueDescriptor(), extractingReturnValueDescriptor(AssertFactory)
|
The method and constructor descriptor assertions add nothing of their own; neither do the return-value and cross-parameter ones beyond their base classes.
final var greet = assertThatBeanDescriptor(validator.getConstraintsForClass(Greeter.class))
.extractingConstraintsForMethod("greet", String.class, int.class);
greet.hasName("greet").hasConstrainedParameters().hasConstrainedReturnValue();
greet.extractingParameterDescriptor(0)
.hasIndex(0)
.hasElementClass(String.class)
.hasConstraints();
greet.extractingReturnValueDescriptor()
.hasConstraints()
.hasElementClass(String.class);
greet.extractingCrossParameterDescriptor()
.doesNotHaveConstraints();
assertThatBeanDescriptor(validator.getConstraintsForClass(Greeter.class))
.extractingConstraintsForConstructor(String.class)
.hasConstrainedParameters()
.hasConstrainedReturnValue();Index contract. extractingParameterDescriptor(int) throws IllegalArgumentException for a negative index, and
fails as an AssertionError — Expecting a parameter at index 2 of <greet> but it has 2 parameter(s) — for an index
the executable does not have. The failure goes through the assertion, so a description set with as(…) is kept.
| Method | |
|---|---|
hasIndex(int), extractingIndex()
|
ParameterDescriptor.getIndex() |
hasName(String), extractingName()
|
getName() |
plus the cascadable/container methods below.
AbstractCascadableContainerDescriptorAssert, for property, parameter, return-value and container-element-type
descriptors:
| Method | |
|---|---|
isCascaded(), isNotCascaded(), extractingCascaded()
|
CascadableDescriptor.isCascaded() |
extractingGroupConversions(), doesNotHaveAnyGroupConversion()
|
getGroupConversions() |
extractingConstrainedContainerElementTypes(), doesNotHaveAnyConstrainedContainerElementType()
|
ContainerDescriptor.getConstrainedContainerElementTypes() |
The property-descriptor assertion adds hasPropertyName(String) / extractingPropertyName().
| Method | |
|---|---|
hasContainerClass(Class), extractingContainerClass()
|
getContainerClass() |
hasTypeArgumentIndex(Integer), extractingTypeArgumentIndex()
|
getTypeArgumentIndex() |
// public final List<@NotBlank String> tags
assertThatBeanDescriptor(validator.getConstraintsForClass(Bagged.class))
.extractingConstraintsForProperty("tags")
.extractingConstrainedContainerElementTypes()
.singleElement(CONTAINER_ELEMENT_TYPE_DESCRIPTOR)
.hasContainerClass(List.class)
.hasTypeArgumentIndex(0)
.hasElementClass(String.class)
.hasConstraints()
.isNotCascaded();| Method | |
|---|---|
convertsGroup(Class from, Class to) |
both ends at once |
extractingFrom(), extractingTo()
|
getFrom(), getTo()
|
public static class Parent {
@Valid
@ConvertGroup(from = Default.class, to = Detailed.class)
public Child child;
}
assertThatBeanDescriptor(validator.getConstraintsForClass(Parent.class))
.extractingConstraintsForProperty("child")
.isCascaded()
.extractingGroupConversions()
.singleElement(GROUP_CONVERSION_DESCRIPTOR)
.convertsGroup(Default.class, Detailed.class);The collection-valued extractions return plain AssertJ CollectionAsserts; singleElement(…), first(…) or
element(int, …) with a factory from InstanceOf Factories continues with a typed assertion.
assertThatConstraintDescriptor(ConstraintDescriptor<T>), also reached from a violation with
extractingConstraintDescriptor():
| Method | |
|---|---|
extractingAnnotation(), extractingAnnotation(Function, AssertFactory)
|
getAnnotation() |
extractingAttributes(), hasAttribute(String, Object)
|
getAttributes(), as a MapAssert<String, Object>
|
extractingComposingConstraints(), doesNotHaveComposingConstraints()
|
getComposingConstraints() |
extractingConstraintValidatorClasses(), hasConstraintValidatorClass(Class)
|
getConstraintValidatorClasses() |
extractingGroups() |
getGroups() |
extractingMessageTemplate(), hasMessageTemplate(String)
|
getMessageTemplate() |
extractingPayload(), hasPayload(Class), doesNotHaveAnyPayload()
|
getPayload() |
hostsConstraintTarget(ConstraintTarget), doesNotHostAnyConstraintTarget()
|
getValidationAppliesTo() |
extractingValueUnwrapping(), hasValueUnwrapping(ValidateUnwrappedValue)
|
getValueUnwrapping() |
isReportedAsSingleViolation(), isNotReportedAsSingleViolation(), extractingReportAsSingleViolation()
|
isReportAsSingleViolation() |
extractingAsUnwrapped(Class, AssertFactory), isEqualToWhenUnwrappedAs(Class, Object)
|
unwrap(Class) |
assertThatConstraintViolation(violation)
.extractingConstraintDescriptor()
.extractingAnnotation()
.isInstanceOf(NotBlank.class);assertj-validation · Apache License 2.0 · io.github.jinahya:assertj-validation · Jakarta Validation 3.0 / 3.1 · AssertJ 3.27+ · Java 17+
Running validation
Inspecting results
Reference
External