@JsonSubTypes.Type names are neglected, only the first name is emitted
andrewbents opened this issue · 2 comments
andrewbents commented
Jackson supports specifying names
for subtypes, so the following is possible
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.EXISTING_PROPERTY,
property = "type",
visible = true
)
@JsonSubTypes({
@JsonSubTypes.Type(value = LongDto.class, names = {"Price", "Duration"}),
@JsonSubTypes.Type(value = BoolDto.class, names = {"Official", "Signer"}),
})
static class AbstractDto {
public String type;
}
static class LongDto extends AbstractDto {
public long value;
@Override
public String toString() {
return "LongDto{" +
"type='" + type + '\'' +
", value=" + value +
'}';
}
}
static class BoolDto extends AbstractDto {
public boolean value;
@Override public String toString() {
return "BoolDto{" +
"type='" + type + '\'' +
", value=" + value +
'}';
}
}
@Test
void test() throws JsonProcessingException {
LongDto priceDto = new LongDto();
priceDto.type = "Price";
priceDto.value = 100;
LongDto durationDto = new LongDto();
durationDto.type = "Duration";
durationDto.value = 2;
BoolDto boolDto = new BoolDto();
boolDto.type = "Official";
boolDto.value = true;
ObjectMapper objectMapper = new ObjectMapper();
String jsonString = objectMapper.writeValueAsString(List.of(priceDto, boolDto, durationDto));
System.out.println(jsonString); // [{"type":"Price","value":100},{"type":"Official","value":true},{"type":"Duration","value":2}]
System.out.println(objectMapper.readValue(jsonString, new TypeReference<List<AbstractDto>>() { })); // [LongDto{type='Price', value=100}, BoolDto{type='Official', value=true}, LongDto{type='Duration', value=2}]
}
I would expect the generator to emit something like this:
export interface AbstractDto {
'type': 'Price' | 'Duration' | 'Official' | 'Signer';
}
export interface BoolDto extends AbstractDto {
type: 'Official' | 'Signer';
value: boolean;
}
export interface LongDto extends AbstractDto {
type: 'Price' | 'Duration'';
value: number;
}
export type AbstractDtoUnion = BoolDto | LongDto;
But the actual output is like this (only first name is taken of each type):
export interface AbstractDto {
type: 'Official' | 'Price';
}
export interface BoolDto extends AbstractDto {
type: 'Official';
value: boolean;
}
export interface LongDto extends AbstractDto {
type: 'Price';
value: number;
}
export type AbstractDtoUnion = LongDto | BoolDto;
is it possible to support this case?
Yidna commented
Likely related to #794
I was running into this issue as well and rolled the version back - it no longer (incorrectly) performs a string breakdown based on the names
and goes back to ignoring the annotation and using the field's type, which is technically more correct
durgasatti commented
make sure you have a .java script for estimating the errors