2017-10-09 91 views
1

我有一個多對一的關係:A * < - >圖1B和欲反序列化從具有的主鍵(一個JSON甲存在於分貝與該主鍵):反序列化外鍵

{ 
    "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創建。我如何反序列化Ab屬性正確實例化從數據庫?

注意:我正在使用傑克遜版本2.6.1。

+0

你想從B信息在哪裏?在數據庫中查看和創建自定義對象,或者只是創建與id字段空? – varren

回答

1

您有幾種選擇,這裏是similar question

  1. @JsonCreatorB類(More info

  2. 自定義解串器

  3. 定製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 { 
        // ... 
    } 
    

這裏是你的情況下,相關gist demo更加廣闊github project有些系列化的想法

+0

嗨@varren,謝謝你的非常有趣的答案。我有一個關於它的問題:我如何將對象庫傳遞給ObjectIdResolver? –

+0

有很多選項可供考慮。 1)注入ObjectIdResolver創建ObjectMapper而不是註解[像這樣](https://gist.github.com/ftagsold/38a92cba5467fe74ae6b)2)使用一些靜態引用到你的版本庫/服務/某些版本庫工廠3)可能只是autowire它[像這裏](https://github.com/terrestris/shogun2/blob/master/src/shogun2-core/src/main/java/de/terrestris/shogun2/converter/PersistentObjectIdResolver.java#L35- L41)更多信息[這裏](https://github.com/terrestris/shogun2/search?utf8=%E2%9C%93&q=PersistentObjectIdResolver&type=) – varren

+0

@ y.luis ppl說你可以使用'SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this );'類似於https://stackoverflow.com/a/21562939/1032167我其實從來沒有太多缺乏它。大概可以嘗試像https://gist.github.com/varren/c84da2f357a1d86b24bf137f3144cc3a#file-myobjectidresolverautowired-java – varren