| validation of nested Optional object throws class cast exception, if the getter is Optional but field for example: following code ends with class cast exception:
private class X {
@Valid
private Y y;
public void setY(Y y) {
this.y = y;
}
public Optional<Y> getY() {
return Optional.ofNullable(y);
}
}
private class Y {
@Valid
private Z z;
public void setZ(Z z) {
this.z = z;
}
public Optional<Z> z() {
return Optional.ofNullable(z);
}
}
private class Z {
@NotNull
private String karel;
@NotNull(groups = Group1.class)
private String johny;
@NotNull
private Integer test;
public String getKarel() {
return karel;
}
public void setKarel(String karel) {
this.karel = karel;
}
public String getJohny() {
return johny;
}
public void setJohny(String johny) {
this.johny = johny;
}
public Optional<Integer> getTest() {
return null;
}
}
private interface Group1 {
}
private ValidationService validationService = validationService();
private ValidationService validationService() {
ValidationServiceImpl service = new ValidationServiceImpl();
return service;
}
@Test
public void test_1() {
X x = new X();
x.y = new Y();
x.y.z = new Z();
x.y.z.test = 1;
Assert.assertEquals(2, validationService.getConstraintViolations(x, Group1.class).size());
}
The problem is that code tries to unwrap that Optional without checking, if the original field value is really Optional (it probably checks only getter) Workaround exist if you explicitly change your classes to "do not unwrap", the validation is successfully finished but I would expected that in this case it should work in this way automatically without that annotation.
private class X {
@Valid
@UnwrapValidatedValue(false)
private Y y;
public void setY(Y y) {
this.y = y;
}
public Optional<Y> getY() {
return Optional.ofNullable(y);
}
}
private class Y {
@Valid
@UnwrapValidatedValue(false)
private Z z;
public void setZ(Z z) {
this.z = z;
}
public Optional<Z> z() {
return Optional.ofNullable(z);
}
}
private class Z {
@NotNull
private String karel;
@NotNull(groups = Group1.class)
private String johny;
@NotNull
@UnwrapValidatedValue(false)
private Integer test;
public String getKarel() {
return karel;
}
public void setKarel(String karel) {
this.karel = karel;
}
public String getJohny() {
return johny;
}
public void setJohny(String johny) {
this.johny = johny;
}
public Optional<Integer> getTest() {
return null;
}
}
private interface Group1 {
}
private ValidationService validationService = validationService();
private ValidationService validationService() {
ValidationServiceImpl service = new ValidationServiceImpl();
return service;
}
@Test
public void test_1() {
X x = new X();
x.y = new Y();
x.y.z = new Z();
x.y.z.test = 1;
Assert.assertEquals(2, validationService.getConstraintViolations(x, Group1.class).size());
}
|