2012-11-29 24 views
8

Sto avendo una relazione bidirezionale da molte a molte nelle mie entità. Vedere l'esempio di seguito:Riferimenti ciclici in una relazione bidirezionale molti a molti

public class Collaboration { 

    @JsonManagedReference("COLLABORATION_TAG") 
    private Set<Tag> tags; 

} 

public class Tag { 

    @JsonBackReference("COLLABORATION_TAG") 
    private Set<Collaboration> collaborations; 

} 

Quando provo a serializzare questo per JSON, sto ottenendo la seguente eccezione: `

"java.lang.IllegalArgumentException: non può essere gestito gestito/indietro riferimento 'COLLABORATION_TAG':. tipo di riferimento all'indietro (java.util.Set) non è compatibile con tipo gestito (foo.Collaboration)

In realtà, so che questo ha un senso, perché il javadoc afferma esplicitamente che non puoi usare @JsonBackReference su Collections. La mia domanda è, come devo affrontare questo problema? Quello che ho fatto per ora è rimuovere l'annotazione @JsonManagedReference sul lato genitore e aggiungere @JsonIgnore sul lato figlio. Qualcuno potrebbe dirmi quali sono gli effetti collaterali di questo approccio? ci sono altri suggerimenti?

+2

È possibile utilizzare Jackson 2.0. Vedi http://stackoverflow.com/questions/10065002/jackson-serialization-of-entities-with-birectional-relationships-avoiding-cyc –

+1

L'annotazione 'JsonIdentityInfo' è adorabile, grazie a @EugeneRetunsky! Ho trovato questa pagina molto utile per imparare come funziona: http://wiki.fasterxml.com/JacksonFeatureObjectIdentity –

+0

Ho provato 'JsonManagedReference' e' JsonBackReference' nessuno di loro funziona. Tuttavia, il collegamento dato da @ SimonAndréForsberg è molto interessante e funziona. – yas

risposta

3

Ho finito per implementare la seguente soluzione.

Un'estremità della relazione è considerata il genitore. Non ha bisogno di alcuna annotazione relativa a Jackson.

public class Collaboration { 

    private Set<Tag> tags; 

} 

L'altro lato della relazione è implementato come segue.

public class Tag { 

    @JsonSerialize(using = SimpleCollaborationSerializer.class) 
    private Set<Collaboration> collaborations; 

} 

Sto usando un serializzatore personalizzato per verificare che non si verifichino riferimenti ciclici. Il serializzatore potrebbe essere implementato in questo modo:

public class SimpleCollaborationSerializer extends JsonSerializer<Set<Collaboration>> { 

    @Override 
    public void serialize(final Set<Collaboration> collaborations, final JsonGenerator generator, 
     final SerializerProvider provider) throws IOException, JsonProcessingException { 
     final Set<SimpleCollaboration> simpleCollaborations = Sets.newHashSet(); 
     for (final Collaboration collaboration : collaborations) { 
      simpleCollaborations.add(new SimpleCollaboration(collaboration.getId(), collaboration.getName()));     
     } 
     generator.writeObject(simpleCollaborations); 
    } 

    static class SimpleCollaboration { 

     private Long id; 

     private String name; 

     // constructors, getters/setters 

    } 

} 

Questo serializzatore mostrerà solo un insieme limitato delle proprietà dell'entità di collaborazione. Poiché la proprietà "tags" viene omessa, non si verificheranno riferimenti ciclici.

È possibile trovare una buona lettura di questo argomento here. Spiega tutte le possibilità quando stai avendo uno scenario simile.

+0

Ho una situazione simile spiegata in http://stackoverflow.com/questions/28179369/spring-rest-json-can-not-handle-managed-back-reference-defaultreference-415 Non sono ancora riuscito a trovare una soluzione diretta con annotazioni. – zencv

1

implementazione dell'interfaccia molto utile è fornito a Jackson 2 biblioteca come

@Entity 
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id") 
public class Collaboration { .... 

in Maven

<dependency> 
    <groupId>com.fasterxml.jackson.core</groupId> 
    <artifactId>jackson-core</artifactId> 
    <version>2.0.2</version> 
</dependency> 
+0

FYI: Penso che la corretta dipendenza da parte del maven dovrebbe essere ' note-jackson'. Questo è quello che ha funzionato per la mia build, comunque. – FrustratedWithFormsDesigner

Problemi correlati