[英]Serialize two different POJO object with the same id with Jackson
I have these two classes:我有这两个类:
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id",scope = Rol.class)
public class Rol extends MyEntity implements Serializable {
private Integer id;
private String rolName;
public Rol(Integer id, String rolName) {
this.id = id;
this.rolName = rolName;
}
...
}
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id",scope = User.class)
public class User extends MyEntity implements Serializable {
private Integer id;
private String name;
private List<Rol> rolList;
public User(Integer id, String name, List<Rol> rolList) {
this.id = id;
this.name = name;
this.rolList = rolList;
}
...
}
and I try to serialize and deserialize the user object as following我尝试序列化和反序列化用户对象如下
Rol rol1 = new Rol(1, "MyRol");
Rol rol2 = new Rol(1, "MyRol");
List<Rol> rolList = new ArrayList();
rolList.add(rol1);
rolList.add(rol2);
user = new User(1, "MyUser", rolList);
ObjectMapper mapper = new ObjectMapper();
String jsonString = mapper.writeValueAsString(user);
User userJson = mappe.readValue(jsonString, User.class);
and the JsonMappingException: Already had POJO for id is produced.并且 JsonMappingException: Already have POJO for id 已生成。 Why?
为什么?
When I review the json result of the serialization I see that the result is当我查看序列化的 json 结果时,我看到结果是
{"id": 1,"name": "MyName","rolList": [{"id": 1,"rolName": "MyRol"},{"id": 1,"rolName": "MyRol"}]}
when the result should be结果应该是什么时候
{"id": 1,"name": "MyName","rolList": [{"id": 1,"rolName": "MyRol"},1]}
because rol1 and rol2 are different instances of the same POJO identifier with id 1.因为 rol1 和 rol2 是 id 为 1 的同一个 POJO 标识符的不同实例。
How can I avoid the JsonMappingException?如何避免 JsonMappingException? In my project I have some different instances of the same POJO.
在我的项目中,我有一些相同 POJO 的不同实例。 I can guarantee that if the id's are equal -> objects are equal.
我可以保证,如果 id 是相等的 -> 对象是相等的。
Excuse me for my bad English.请原谅我的英语不好。
For anyone returning to this question, it looks like there's option to do this with a custom ObjectIdResolver in Jackson.对于任何返回此问题的人,似乎可以选择使用 Jackson 中的自定义 ObjectIdResolver 来执行此操作。 You can specify this on the @JsonIdentityInfo annotation, eg :
您可以在 @JsonIdentityInfo 注释上指定它,例如:
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "name",
resolver = CustomObjectIdResolver.class)
Then perhaps wrap the normal SimpleObjectIdResolver class to get going and customise bindItem().然后也许包装正常的 SimpleObjectIdResolver 类以开始并自定义 bindItem()。
In my case I wanted to avoid overlapping objectIds, so cleared down the references when I started a new Something:在我的例子中,我想避免重叠 objectId,所以当我开始一个新的东西时清除引用:
public class CustomObjectIdResolver implements ObjectIdResolver {
private ObjectIdResolver objectIdResolver;
public CustomObjectIdResolver() {
clearReferences();
}
@Override
public void bindItem(IdKey id, Object pojo) {
// Time to drop the references?
if (pojo instanceof Something)
clearReferences();
objectIdResolver.bindItem(id, pojo);
}
@Override
public Object resolveId(IdKey id) {
return objectIdResolver.resolveId(id);
}
@Override
public boolean canUseFor(ObjectIdResolver resolverType) {
return resolverType.getClass() == getClass();
}
@Override
public ObjectIdResolver newForDeserialization(Object context) {
return new CustomObjectIdResolver();
}
private void clearReferences() {
objectIdResolver = new SimpleObjectIdResolver();
}
}
Jackson expects in this case different id
for different class instances.在这种情况下,杰克逊期望不同的类实例有不同的
id
。 There has been a previous discussion at github here .之前在 github这里有过讨论。 Overriding
hashCode
and equals
will not help.覆盖
hashCode
和equals
将无济于事。 Object references must match for equal id
.对象引用必须匹配相等的
id
。
Options选项
Rol
instances instead of making new ones with equal fields.Rol
实例而不是创建具有相同字段的新实例。 As a bonus you will also save memory.@JsonIdentityInfo
@JsonIdentityInfo
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.