簡體   English   中英

使用 Jackson 序列化兩個具有相同 id 的不同 POJO 對象

[英]Serialize two different POJO object with the same id with Jackson

我有這兩個類:

@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;
    }

    ...
}

我嘗試序列化和反序列化用戶對象如下

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);

並且 JsonMappingException: Already have POJO for id 已生成。 為什么?

當我查看序列化的 json 結果時,我看到結果是

{"id": 1,"name": "MyName","rolList": [{"id": 1,"rolName": "MyRol"},{"id": 1,"rolName": "MyRol"}]}

結果應該是什么時候

{"id": 1,"name": "MyName","rolList": [{"id": 1,"rolName": "MyRol"},1]}

因為 rol1 和 rol2 是 id 為 1 的同一個 POJO 標識符的不同實例。

如何避免 JsonMappingException? 在我的項目中,我有一些相同 POJO 的不同實例。 我可以保證,如果 id 是相等的 -> 對象是相等的。

請原諒我的英語不好。

對於任何返回此問題的人,似乎可以選擇使用 Jackson 中的自定義 ObjectIdResolver 來執行此操作。 您可以在 @JsonIdentityInfo 注釋上指定它,例如:

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "name", 
    resolver = CustomObjectIdResolver.class)

然后也許包裝正常的 SimpleObjectIdResolver 類以開始並自定義 bindItem()。

在我的例子中,我想避免重疊 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();
        }
    }

在這種情況下,傑克遜期望不同的類實例有不同的id 之前在 github這里有過討論。 覆蓋hashCodeequals將無濟於事。 對象引用必須匹配相等的id

選項

  1. 重用Rol實例而不是創建具有相同字段的新實例。 作為獎勵,您還可以節省內存。
  2. 修改應用邏輯,使其不依賴於@JsonIdentityInfo

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM