使用外键从JSON反序列化

时间:2017-10-09 16:23:23

标签: java json jpa serialization jackson

我有多对一的关系: A *&lt; - &gt; 1 B 我希望从 B <的JSON反序列化 A / strong>的主键( B 存在于具有该主键的数据库中):

{
    "b": 1
}

我尝试了以下内容:

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

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

但是使用b = null创建了对象 A 。如何从正确实例化 b 属性反序列化 A

注意:我使用的是Jackson 2.6.1。

1 个答案:

答案 0 :(得分:1)

您有几个选项,这里是similar question

    {li>

    @JsonCreator工厂B班级(More info

  1. 自定义反序列化程序

  2. ObjectIdResolver的自定义@JsonIdentityInfo

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

    并像这样使用它:

    @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,
            resolver = MyObjectIdResolver.class, 
            property = "id", scope = B.class)
    public class B  {
       // ...
    }
    
  3. 以下是您的案例gist demo更广泛github project的一些序列化想法