I think this can be better explained with an example(code is below). Suppose I have BaseClass and some sub-classes like Employee, Contractor etc. I do not want a database table for BaseClass(Hence using @MappedSuperClass). BaseClass has some common fields, but entityType is not a valid database field in any subclass like Employee, Contrator (Hence I denoted it as @Transient). Now I get back a json that has all the Employee values, it does not have endDate value that is in the BaseClass. I want to set the BaseClass's common fields like endDate in the Employee class and save it to the Employee table.
When retrieving I want to retrieve all Employees that have an endDate as some value. This should be possible because I did save the endDate when saving my Employee records.
Additional Info: I'm having trouble getting this to work. I'm using openAPI and I understood that I need this discriminator column to have a super class-sub class relationship generated - Inheritance from empty abstract class using openapi 3.0.
@JsonIgnoreProperties(
value = "entityType", // ignore manually set entityType, it will be automatically generated by Jackson during serialization
allowSetters = true // allows the entityType to be set during deserialization
)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "entityType", visible = true)
@JsonSubTypes({
@JsonSubTypes.Type(value = Employee.class, name = "Employee")
@JsonSubTypes.Type(value = Contractor.class, name = "Contractor")
})
@jakarta.persistence.MappedSuperclass
public abstract BaseClass{
//common to all sub-classes
LocalDate endDate;
/**
Gets or Sets entityType
*/
public enum EntityTypeEnum {
Employee("Employee");
Contractor("Contractor");
private String value;
EntityTypeEnum(String value) {
this.value = value;
}
@JsonValue
public String getValue() {
return value;
}
@Override
public String toString() {
return String.valueOf(value);
}
@JsonCreator
public static EntityTypeEnum fromValue(String value) {
for (EntityTypeEnum b : EntityTypeEnum.values()) {
if (b.value.equals(value)) {
return b;
}
}
throw new IllegalArgumentException("Unexpected value '" + value + "'");
}
}
@JsonProperty("entityType")
@jakarta.persistence.Transient
private EntityTypeEnum entityType;
}
public Employee extends BaseClass {...}
public Contractor extends BaseClass{...}
How would this deserializing work if I know that I'm de-serializing Employee.class, but the Json for employees that I receive does not have the entityType as a property at all? Currently I get 'missing type id property 'entityType'' I want to de-serialize a json of Employees to List class. The Json does not have entityType or any superclass(i.e. BaseClass from the above example) fields.
So to summarize, I want Jackson and JPA to play nicely with each other.
- I want to Jackson to correctly read a json, where the json has only the Employee related values(no superclass values yet) (At runtime I will know that I have Employee.class).
- I want to save this to the Employees table after setting my own values like endDate(which are in the BaseClass).
- I want to retrive this later, from the Employees table, knowing taht I have the endDate and Employee.class value at runtime.
Hope this makes sense. If not let me rephrase my questions: OpenAPI requires me to use the discriminator, in this case we call it entityType, for the inheritance to work when the classes are generated. But when I do that, Jackson complains that it cannot find the property id entityType when serializing a json. The json obviously does not have a field called entityType because we created this field. I tired variaous apporached including using : 1.
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.enable(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE);
Adding the following to the top of the BaseClass:
@JsonIgnoreProperties(
value = "entityType", // ignore manually set entityType, it will be automatically generated by Jackson during serialization
allowSetters = true // allows the entityType to be set during deserialization
)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "entityType")
and I still get this error com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Could not resolve subtype of [simple type, class Employee]: missing type id property 'entityType'