Reputation: 577
My Json looks like following
{
name: "math",
code:null,
description:"Mathematics",
id:null,
name:"math",
noExam:null,
teacher:{
id: "57869ced78aa7da0d2ed2d92",
courseGroup:"LKG",
experties:[{type: "SOCIALSTUDIES", id: "3"}, {type: "PHYSICS", id: "4"}]
},
id:"57869ced78aa7da0d2ed2d92"
}
if you see my entity classes, I have a set of enums in Teacher.java
When I try to post this I get error
JsonMappingException: Can not deserialize instance of com.iris.fruits.domain.enumeration.Experties out of START_OBJECT token
I have tried almost all solutions out there, like DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY
, but without success.
public class Subject implements Serializable {
// all the other fields
@JoinColumn(name = "teacher_id")
private Teacher teacher;
// getter and setter
}
public class Teacher implements Serializable {
// all the other fields
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private String id;
@Enumerated(EnumType.STRING)
@Column(name = "experties")
@JsonProperty("experties")
private List< Experties> experties;
// getter and setter
}
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum Experties implements Serializable {
MATH(1,"MATH"),
SCIENCE(2,"SCIENCE"),
SOCIALSTUDIES(3,"SOCIALSTUDIES"),
PHYSICS(4,"PHYSICS"),
CHEMISTRY(5,"CHEMISTRY");
@JsonSerialize(using = ToStringSerializer.class)
private String type;
@JsonSerialize(using = ToStringSerializer.class)
private Integer id;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
Experties(Integer id, final String type) {
this.id = id;
this.type = type;
}
}
Upvotes: 5
Views: 9825
Reputation: 1847
You have this issue because you have a custom serializer in your enum @JsonFormat(shape = JsonFormat.Shape.OBJECT)
. Jackson does not know how to deserialize object from json, into enum. You can create "creator" method to solve this easily:
public enum Experties implements Serializable {
@JsonCreator
public Experties(String type) {
// here you can use "type" attribute from json object to create your Enum instance. If you need, you can also add as parameter "Integer Id", as it is in your enum json representation.
return valueOf(type);
}
}
Upvotes: 0
Reputation: 5251
You have this issue because you have a custom serializer in your enum
(@JsonFormat(shape = JsonFormat.Shape.OBJECT)
). Thus, to solve the issue, you need a custom deserializer.
You can define a custom deserializer using :
@JsonFormat(shape = JsonFormat.Shape.OBJECT) // custom serializer
@JsonDeserialize(using = MyEnumDeserializer.class) // custom deserializer
public enum Experties implements Serializable {
...
}
The custom deserializer being :
public static class MyEnumDeserializer extends JsonDeserializer<Experties> {
@Override
public Experties deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
JsonNode node = jsonParser.getCodec().readTree(jsonParser);
String type = node.get("type").asText();
return Stream.of(Experties.values())
.filter(enumValue -> enumValue.getType().equals(type))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("type "+type+" is not recognized"));
}
}
Of course, you can have another deserializer implementation (e.g. use the id
field instead of the type
field, check the coherence between the id
and type
fields).
Upvotes: 4
Reputation: 131
Add JsonDeserialize annotation to experties setter in Teacher class:
@JsonDeserialize(using = EnumDeserializer.class)
public void setExperties(List experties){
//...
}
Upvotes: 0
Reputation: 79
Your class should match with the structure of the json. And in your input json shouldn't repeat keys.
I guess you classes, should like below:
public class Subject implements Serializable {
// all the other fields
String name;
String code;
String description;
String id;
String noExam;
@JoinColumn(name = "teacher_id")
private Teacher teacher;
// getter and setter
}
public class Teacher implements Serializable {
// all the other fields
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private String id;
@Enumerated(EnumType.STRING)
@Column(name = "experties")
@JsonProperty("experties")
private List< Experties> experties;
String courseGroup;
// getter and setter
}
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum Experties implements Serializable {
MATH(1,"MATH"),
SCIENCE(2,"SCIENCE"),
SOCIALSTUDIES(3,"SOCIALSTUDIES"),
PHYSICS(4,"PHYSICS"),
CHEMISTRY(5,"CHEMISTRY");
@JsonSerialize(using = ToStringSerializer.class)
private String type;
@JsonSerialize(using = ToStringSerializer.class)
private Integer id;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
Experties(Integer id, final String type) {
this.id = id;
this.type = type;
}
}
Upvotes: 0