Reputation: 5001
I'm having a bidirectional many to many relationship in my entities. See the example below:
public class Collaboration {
@JsonManagedReference("COLLABORATION_TAG")
private Set<Tag> tags;
}
public class Tag {
@JsonBackReference("COLLABORATION_TAG")
private Set<Collaboration> collaborations;
}
When I try to serialize this to JSON, I'm getting the following exception: `
"java.lang.IllegalArgumentException: Can not handle managed/back reference 'COLLABORATION_TAG': back reference type (java.util.Set) not compatible with managed type (foo.Collaboration).
Actually, I know this makes sense because the javadoc explicitly states that you can't use @JsonBackReference on Collections. My question is, how should I address this problem? What I've done for now is remove the @JsonManagedReference annotation on the parent side, and added the @JsonIgnore on the child side. Could someone tell me what the side effects are of this approach? Are there any other suggestions?
Upvotes: 9
Views: 11767
Reputation: 2426
very handy interface implementation is provided in jackson 2 library as
@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>
Upvotes: 1
Reputation: 5001
I ended up implementing the following solution.
One end of the relationship is considered to be the parent. It does not need any Jackson related annotation.
public class Collaboration {
private Set<Tag> tags;
}
The other side of the relationship is implemented as follows.
public class Tag {
@JsonSerialize(using = SimpleCollaborationSerializer.class)
private Set<Collaboration> collaborations;
}
I'm using a custom serializer to will make sure that no cyclic references will occur. The serializer could be implemented like this:
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
}
}
This serializer will only show a limited set of the properties of the Collaboration entity. Because the "tags" property is omited, no cyclic references will occur.
A good read about this topic can be found here. It explains all possibilities when you're having a similar scenario.
Upvotes: 4