Seamus McMorrow
Seamus McMorrow

Reputation: 273

Jackson Deep Nested Objects

I have the following java JPA objects which are converted to json in my spring rest controller method, they are

class User{
    @JsonManagedReference
    @OneToMany
    private Portfolio portfolio;
    .....
}

class Portfolio {
     @JsonBackReference
     @ManyToOne
 private User user;

    @JsonManagedReference
     private List<Order> orders;
     .....
}

class Order {
     @JsonBackReference
 private Portfolio portfolio;

     private User user;
}

In my application I need 2 services:

  1. Logon: returns the User object, with the Portfolio and List of Orders object, I don't need the Order.user object for this.

  2. GetOrders: returns a List of Orders and I need the Order.user object with this.

Order.user is not the same as the parent User object.

My question is how to do I avoid an infinite recursion problem with the User object? Or is this just a bad design?

Upvotes: 1

Views: 3156

Answers (1)

Perception
Perception

Reputation: 80593

The problem with @JsonManagedReference and @JsonBackReference is that they handle a very specific kind of (direct) cyclic reference well, but are not designed to process anything outside of that narrow window (where a single parent object is directly related to one or more child objects). Unfortunately, your use case doesn't fall within that window.

So you have two options:

  • Manual workaround - In your service class you would need to remove (make null) the order.user property, prior to serializing the top level user object. And conversely, you would need to remove (make null) the user.portfolio.orders property, prior to serializing the orders.

  • Framework workaround - Upgrade to Jackson 2.0+ and use @JsonIdentityInfo. It can properly handle object references in graphs, many-to-many relationships, deep object trees, and more. Some documentation and examples.

You can also get around the problem if you have control over the ObjectMapper. If you do then you simply need to specify a custom serializer to use depending on which of the objects you are returning, but since you are working within the Spring framework I do not believe you have direct control over the mapper.

My personal recommendation would be to upgrade your Jackson library and use @JsonIdentityInfo.

Upvotes: 2

Related Questions