Skip to content

Commit 8b53fec

Browse files
committed
Use List for violations in ParameterErrors
See gh-29825
1 parent 425d5a9 commit 8b53fec

File tree

3 files changed

+32
-17
lines changed

3 files changed

+32
-17
lines changed

spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationAdapter.java

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ private final class ValueResultBuilder {
350350

351351
private final List<MessageSourceResolvable> resolvableErrors = new ArrayList<>();
352352

353-
private final Set<ConstraintViolation<Object>> violations = new LinkedHashSet<>();
353+
private final List<ConstraintViolation<Object>> violations = new ArrayList<>();
354354

355355
public ValueResultBuilder(Object target, MethodParameter parameter, @Nullable Object argument) {
356356
this.target = target;
@@ -359,8 +359,8 @@ public ValueResultBuilder(Object target, MethodParameter parameter, @Nullable Ob
359359
}
360360

361361
public void addViolation(ConstraintViolation<Object> violation) {
362-
this.violations.add(violation);
363362
this.resolvableErrors.add(createMessageSourceResolvable(this.target, this.parameter, violation));
363+
this.violations.add(violation);
364364
}
365365

366366
public ParameterValidationResult build() {
@@ -449,8 +449,22 @@ public int compare(ParameterValidationResult result1, ParameterValidationResult
449449
Integer containerIndex2 = errors2.getContainerIndex();
450450
if (containerIndex1 != null && containerIndex2 != null) {
451451
i = Integer.compare(containerIndex1, containerIndex2);
452-
return i;
452+
if (i != 0) {
453+
return i;
454+
}
453455
}
456+
i = compareKeys(errors1, errors2);
457+
return i;
458+
}
459+
return 0;
460+
}
461+
462+
@SuppressWarnings("unchecked")
463+
private <E> int compareKeys(ParameterErrors errors1, ParameterErrors errors2) {
464+
Object key1 = errors1.getContainerKey();
465+
Object key2 = errors2.getContainerKey();
466+
if (key1 instanceof Comparable<?> && key2 instanceof Comparable<?>) {
467+
return ((Comparable<E>) key1).compareTo((E) key2);
454468
}
455469
return 0;
456470
}

spring-context/src/main/java/org/springframework/validation/beanvalidation/ParameterErrors.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,8 @@
1616

1717
package org.springframework.validation.beanvalidation;
1818

19-
import java.util.ArrayList;
19+
import java.util.Collection;
2020
import java.util.List;
21-
import java.util.Set;
2221

2322
import jakarta.validation.ConstraintViolation;
2423

@@ -66,10 +65,10 @@ public class ParameterErrors extends ParameterValidationResult implements Errors
6665
*/
6766
public ParameterErrors(
6867
MethodParameter parameter, @Nullable Object argument, Errors errors,
69-
Set<ConstraintViolation<Object>> violations,
68+
Collection<ConstraintViolation<Object>> violations,
7069
@Nullable Object container, @Nullable Integer index, @Nullable Object key) {
7170

72-
super(parameter, argument, new ArrayList<>(errors.getAllErrors()), violations);
71+
super(parameter, argument, errors.getAllErrors(), violations);
7372

7473
this.errors = errors;
7574
this.container = container;

spring-context/src/main/java/org/springframework/validation/beanvalidation/ParameterValidationResult.java

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616

1717
package org.springframework.validation.beanvalidation;
1818

19+
import java.util.Collection;
1920
import java.util.List;
20-
import java.util.Set;
2121

2222
import jakarta.validation.ConstraintViolation;
2323

@@ -51,23 +51,24 @@ public class ParameterValidationResult {
5151

5252
private final List<MessageSourceResolvable> resolvableErrors;
5353

54-
private final Set<ConstraintViolation<Object>> violations;
54+
private final List<ConstraintViolation<Object>> violations;
5555

5656

5757
/**
5858
* Create a {@code ParameterValidationResult}.
5959
*/
6060
public ParameterValidationResult(
61-
MethodParameter methodParameter, @Nullable Object argument, List<MessageSourceResolvable> errors,
62-
Set<ConstraintViolation<Object>> violations) {
61+
MethodParameter methodParameter, @Nullable Object argument,
62+
Collection<? extends MessageSourceResolvable> resolvableErrors,
63+
Collection<ConstraintViolation<Object>> violations) {
6364

64-
Assert.notNull(methodParameter, "`MethodParameter` is required");
65-
Assert.notEmpty(errors, "`resolvableErrors` must not be empty");
65+
Assert.notNull(methodParameter, "MethodParameter is required");
66+
Assert.notEmpty(resolvableErrors, "`resolvableErrors` must not be empty");
6667
Assert.notEmpty(violations, "'violations' must not be empty");
6768
this.methodParameter = methodParameter;
6869
this.argument = argument;
69-
this.resolvableErrors = List.copyOf(errors);
70-
this.violations = violations;
70+
this.resolvableErrors = List.copyOf(resolvableErrors);
71+
this.violations = List.copyOf(violations);
7172
}
7273

7374

@@ -110,9 +111,10 @@ public List<MessageSourceResolvable> getResolvableErrors() {
110111
}
111112

112113
/**
113-
* The violations associated with the method parameter.
114+
* The violations associated with the method parameter, in the same order
115+
* as {@link #getResolvableErrors()}.
114116
*/
115-
public Set<ConstraintViolation<Object>> getViolations() {
117+
public List<ConstraintViolation<Object>> getViolations() {
116118
return this.violations;
117119
}
118120

0 commit comments

Comments
 (0)