Reputation: 11
I have two entity User and Group and the relationship between both entities are many-to-many. When I call view-group/groupName
, I am getting the list of users of group as expected. But when I call view-user/userEmail
, I am not getting the list of groups with user details of which user is part of.
Group.java
@Entity
@Table(name = "group_")
public class Group {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotBlank
private String groupName;
@ManyToMany
@JoinTable(name = "group_user",
joinColumns = { @JoinColumn(name = "group_id") },
inverseJoinColumns = {@JoinColumn(name = "user_id") })
public Set<User> usersOfgroup = new HashSet<>();
public Group() {
}
}
User.java
@Entity
@Table(name="users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotBlank
@Column(name="name")
private String name;
@NotBlank
@Column(name="email")
private String email;
@JsonIgnore
@ManyToMany(mappedBy = "usersOfgroup")
public Set<Group> memberInGroups =new HashSet<>();
public User() {
}
localhost:8080/view-group/groupName
{
"id": 1,
"groupName": "Group1",
"usersOfgroup": [
{
"id": 2,
"name": "Abhishek",
"email": "[email protected]",
}
]
}
localhost:8080/view-user/[email protected]
{
"id": 2,
"name": "Abhishek",
"email": "[email protected]",
}
Expected response :
{
"id": 2,
"name": "Abhishek",
"email": "[email protected]",
"memberInGroups":[
{
"id": 1,
"groupName": "Group1",
}
]
}
Upvotes: 1
Views: 1284
Reputation: 146
You can go with below. It will address your immediate need for this specific case. Usually for a many-to-many, bi-directional relationship with lists, usually the solution is to decide which side of your relation is dominant and to have a JsonManagedReference and JsonBackReference combo, or use @JsonIdentityInfo if you have a list. Below is very good read on bidirectional cases to avoid infinite loops..
https://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion
Coming to the solution I am referring to, you will have to override the getter of the list attribute and also use a @JsonInclude
In your Group class - use @JsonIgnore as shown and also put the getter as below to manually kill the loop
@ManyToMany
@JoinTable(name = "group_user", joinColumns = { @JoinColumn(name = "group_id") }, inverseJoinColumns = {
@JoinColumn(name = "user_id") })
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public Set<User> usersOfgroup = new HashSet<>();
public Set<User> getUsersOfgroup() {
return this.usersOfgroup.stream().map(user -> {
user.memberInGroups = new HashSet<>();
return user;
}).collect(Collectors.toSet());
}
and in your User class, too do the same.
@ManyToMany(mappedBy = "usersOfgroup")
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public Set<Group> memberInGroups = new HashSet<>();
public Set<Group> getMemberInGroups() {
return this.memberInGroups.stream().map(group -> {
group.usersOfgroup = new HashSet<>();
return group;
}).collect(Collectors.toSet());
}
Upvotes: 0
Reputation: 21
You have added @JsonIgnore
on public Set<Group> memberInGroups =new HashSet<>();
, thats why the json response doesn't have the data for this. Remove the annotation and you will see the expected response
The @JsonIgnore
annotation is used to ignore the logical property used in serialization and deserialization.
Upvotes: 1