I am trying to simulate the oneOf construct from OpenAPI spec in my spring-boot application. I have an abstract class Apple
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "color")
@JsonSubTypes({
@JsonSubTypes.Type(value = RedApple.class, name = "RED"),
@JsonSubTypes.Type(value = GreenApple.class, name = "GREEN")
})
public abstract class Apple {
@NotNull
private Color color;
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
public enum Color {
RED, GREEN
}
}
and two subclasses
public class RedApple extends Apple {
}
public class GreenApple extends Apple {
}
Also here is my rest controller
@RestController
@RequestMapping("/apples")
public class AppleController {
@PostMapping
public ResponseEntity<Void> createApple(@Valid @RequestBody Apple apple) {
return ResponseEntity.created(URI.create("/foo")).build();
}
}
The problem is that @Valid does not validate the enum field correctly. Even if I send {"color": "RED"} as a body, the validation fails with a message saying that color must not be null
When I do the exact same thing with a non-abstract class and without JsonSubTypes & JsonTypeInfo annotations everything works like a charm. What am I missing here?
Thanks
CodePudding user response:
The object you are trying to create is of the abstract class, as we know Abstract classes cannot be instantiated the whole idea of abstraction is to refrain from access of that class itself, instead if you pass the class object which has implemented the abstract class would solve your issue
eg to pass RED
public ResponseEntity<Void> createApple(@Valid @RequestBody RedApple apple) {
return ResponseEntity.created(URI.create("/foo")).build();
}
CodePudding user response:
adding visible = true
as parameter to the JsonTypeInfo solved the issue
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, visible = true, property = "color")