-
Notifications
You must be signed in to change notification settings - Fork 248
Description
We ran into breaking changes when upgrading to v2.28.785, due to the new feature in #582. When using JsonTypeInfo in combination with a default class implementation (defaultImpl), then the resulting Tagged Union will capture all the @JsonSubTypes (as a result of #582) but miss the ones covered by the fallback defaultImpl. Not a bug, but perhaps a missing feature?
The short version
In v2.27.744, the provided example generates:
export interface INamedEntity {
type?: INamedEntityType;
entity?: string;
}
export enum INamedEntityType {
O = "O",
NORP = "NORP",
ORGANIZATION = "ORGANIZATION",
FACILITY = "FACILITY",
}
In v2.28.785, the provided example generates:
export interface INamedEntity {
type: "DefaultEntity" | "FACILITY";
entity?: string;
}
export enum INamedEntityType {
O = "O",
NORP = "NORP",
ORGANIZATION = "ORGANIZATION",
FACILITY = "FACILITY",
}
Issue: Valid values for INamedEntity.type are the enums in INamedEntityType, not "DefaultEntity" | "FACILITY"
The verbose version
The issue is a result of having a default fallback implementation (defaultImpl = DefaultEntity.class in the example) in combination with JsonTypeInfo.Id.NAME and JsonTypeInfo.As.EXISTING_PROPERTY. The example has an enum as the name property but I assume the issue will be present also with a String.
Is there a way of keeping the pre-2.28.785 behaviour, or perhaps have the type attribute include all the enum values? Creating an object in the TypeScript domain that implements INamedEntity will, for obvious reasons fail, when setting type='NORP'.
A complete example is provided here: https://github.com/avtalsbanken/typescript-generator
Code from the example repo included below:
package my.example.app;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.EXISTING_PROPERTY,
property = "type",
defaultImpl = DefaultEntity.class
)
@JsonSubTypes({
@JsonSubTypes.Type(
value = FacilityEntity.class,
name = "FACILITY"
)
})
abstract class NamedEntity {
public final NamedEntityType type;
private String entity;
public NamedEntity(NamedEntityType type) {
this.type = type;
}
public String getEntity() {
return entity;
}
public void setEntity(String entity) {
this.entity = entity;
}
}
package my.example.app;
/**
* A tiny subset of Named Entities
*/
public enum NamedEntityType {
O /* Other */,
NORP /* Nationalities or religious or political groups */,
ORGANIZATION /* Companies, agencies, institutions, etc */,
FACILITY /* Buildings, airports, highways, bridges, etc. */
}
package my.example.app;
public class DefaultEntity extends NamedEntity{
public DefaultEntity(NamedEntityType type) {
super(type);
}
}
package my.example.app;
public class FacilityEntity extends NamedEntity {
private String geoCoordinates;
public FacilityEntity() {
super(NamedEntityType.FACILITY);
}
public String getGeoCoordinates() {
return geoCoordinates;
}
public void setGeoCoordinates(String geoCoordinates) {
this.geoCoordinates = geoCoordinates;
}
}