2017-10-09 8 views
1

Ich habe eine viele zu einer Beziehung: A * < -> 1 B und ich möchte Ein aus einer JSON deserialisieren mit B ‚s Primärschlüssel (B existiert in db mit dem Primärschlüssel):Deserialisieren von JSON mit Fremdschlüssel

{ 
    "b": 1 
} 

ich folgendes versucht:

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

und

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

aber Objekt A mit b = null erstellt wird. Wie kann ich A mit b Eigenschaft deserialisieren, die Eigenschaft korrekt von db instanziiert?

Hinweis: Ich verwende Jackson Version 2.6.1.

+0

, wo Sie die b Informationen erhalten tun? in db suchen und benutzerdefiniertes Objekt erstellen oder einfach leer mit ID-Feld erstellen? – varren

Antwort

1

Sie haben mehrere Möglichkeiten, und hier ist similar question:

  1. @JsonCreator Fabrik in B Klasse (More info)

  2. Individuelle Deserializer

  3. Individuelle ObjectIdResolver für @JsonIdentityInfo wie

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

    Und es wie folgt verwenden:

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

Hier ist Ihr Fall gist demo breite github project mit einiger Serialisierung Gedanken im Zusammenhang

+0

Hallo @ Varren, danke für deine sehr interessante Antwort. Ich habe eine Frage dazu: Wie kann ich ein Objekt-Repository an den 'ObjectIdResolver' übergeben? –

+0

Es gibt viele Optionen zu berücksichtigen. 1) InjectIdResolver auf ObjectMapper-Erstellung und nicht in Annotation injizieren [so] (https://gist.github.com/ftagsold/38a92cba5467fe74ae6b) 2) Verwenden Sie wahrscheinlich einen statischen Verweis auf Ihre Repository/Service/einige Repository-Fabrik 3) einfach autowire [wie hier] (https://github.com/terrestris/shogun2/blob/master/src/shogun2-core/src/main/java/de/terrestris/shogun2/converter/PersistentObjectIdResolver.java#L35- L41) mehr Info [hier] (https://github.com/terrestris/shogun2/search?utf8=%E2%9C%93&q=PersistentObjectIdResolver&type=) – varren

+0

@ y.luis ppl sagen Sie können 'SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext (this); ähnlich wie https://stackoverflow.com/a/21562939/1032167 hatte ich eigentlich nie viel Mangel damit. Kann wahrscheinlich etwas wie https://gist.github.com/varren/c84da2f357a1d86b24bf137f3144cc3a#file-myobjectidresolverautowired-java ausprobieren – varren