Deserializing from JSON using foreign key

徘徊边缘 提交于 2021-01-28 06:07:49

问题


I have a many to one relationship: A *<-->1 B and I want to deserialize A from a JSON having B's primary key (B exists in db with that primary key):

{
    "b": 1
}

I have tried the following:

@Entity
@Table(name = "table_a")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class A implements Serializable {

    @JsonIgnore
    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name = "b", unique = true, nullable = false)
    private B b;
}

and

@Entity
@Table(name = "table_b")
public class B implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;

    @OneToMany(mappedBy = "b")
    private List<A> a = new ArrayList<>();
}

but object A is created with b = null. How can I deserialize A with b property correctly instantiated from db?

Note: I am using Jackson version 2.6.1.


回答1:


You have several options and here is similar question :

  1. @JsonCreator factory in B class (More info)

  2. Custom deserializer

  3. Custom ObjectIdResolver for @JsonIdentityInfo like

    private class MyObjectIdResolver implements ObjectIdResolver {
        private Map<ObjectIdGenerator.IdKey,Object> _items  = new HashMap<>();
    
        @Override
        public void bindItem(ObjectIdGenerator.IdKey id, Object pojo) {
            if (!_items.containsKey(id)) _items.put(id, pojo); 
        }
    
        @Override
        public Object resolveId(ObjectIdGenerator.IdKey id) {
            Object object = _items.get(id);
            return object == null ? getById(id) : object;
        }
    
        protected Object getById(ObjectIdGenerator.IdKey id){
            Object object = null;
            try {
                //can resolve object from db here
                //objectRepository.getById((Integer)idKey.key, idKey.scope)
                object = id.scope.getConstructor().newInstance();
                id.scope.getMethod("setId", int.class).invoke(object, id.key);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return object;
        }
    
        @Override
        public ObjectIdResolver newForDeserialization(Object context) {
            return new MyObjectIdResolver();
        }
    
        @Override
        public boolean canUseFor(ObjectIdResolver resolverType) {
            return resolverType.getClass() == getClass();
        }
    }
    

    And use it like this:

    @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,
            resolver = MyObjectIdResolver.class, 
            property = "id", scope = B.class)
    public class B  {
       // ...
    }
    

Here is your case related gist demo more broad github project with some serialization thoughts



来源:https://stackoverflow.com/questions/46650940/deserializing-from-json-using-foreign-key

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!