Issue
I have a many to many relationship in my project between User and a Product. A User can have many products and a Product can be owned by many Users.
User.java
@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinTable( name = "user_product",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "product_id"))
private List<Product> listOfProductsForUser;
Product.java
@JsonIgnore
@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "listOfProductsForUser")
private List<User> listOfUsersForProduct;
In my controller, I have a path that gets me all the users and the nested products associated with the user like this.
[
{
"userId": 1,
"userName": "Fido",
"age": 3,
"listOfProductsForUser": [
{
"productId": 1,
"productName": "tooth brush",
},
{
"productId": 2,
"productName": "potatoes",
},
{
"productId": 3,
"productName": "carrot",
}
]
},
{
"userId": 2,
"userName": "David",
"age": 12,
"listOfProductsForUser": [
{
"productId": 6,
"productName": "oranges",
},
{
"productId": 7,
"productName": "tomatoes",
},
{
"productId": 6,
"productName": "buns",
}
]
}
]
This is fine but I now want to get all products which should have nested users (to get all products and see which users are using them).
While attempting to do this I run into a recursive problem and I have used JsonIgnore on the product.java's listOfProductsForUser
variable as shown above to stop the recursion. How can I accomplish this?
Solution
There are couple of ways to deal with this bi-directional relationship issue. I think @JsonIdentityInfo
is the best way in your case.
What you need to do is change your User
and Product
class as follows.
//other annotations
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "userId")
public class User {
// your code
}
//other annotations
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "productId")
public class Product {
// your code
}
Note: For more info here
Answered By - ray