Reputation: 157
I will be much apprecaite for you to explain my questions.
I have 2 entity and 1 bridge table entity,
Let's say they are Team, User and TeamUser.
TeamEntity:
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "TEAM_ID")
private Integer id;
@JsonManagedReference
@OneToMany(mappedBy = "team", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<TeamUsers> team_users = new HashSet<>();
UserEntity:
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@JsonBackReference
@OneToMany(mappedBy = "user")
private Set<TeamUsers> team_users = new HashSet<>();
TeamUserEntity(bridge table): @EmbeddedId private TeamUsersId id;
@ManyToOne
@MapsId("teamId")
@JoinColumn(name = "team_id")
@JsonBackReference
private Team team;
@ManyToOne
@MapsId("userId")
@JoinColumn(name = "user_id")
@JsonManagedReference
private User user;
@Column(name = "active")
private int active;
As you can see I used @JsonManagedReference and @JsonBackReference to telling the program the direction for the query of the Entity and avoid infinite recrusive.
Now if I run get repo.findAll() on Team CRUDrepository I will get all Team object, and within the content I will get all bridge table data and it also include User details information.
But Let's say sometimes if I want to query the data in oppisite way, I want to get All User information and the object should contain all Team information, looks like the annotation @JsonManagedReference and @JsonBackReference block the result.
In real world development, how should we manage here?
Upvotes: 3
Views: 7775
Reputation: 2947
The @JsonManagedReference
and @JsonBackReference
annotations are used to handle circular references. They can be used to create a JSON structure in a bidirectional way. The @JsonManagedReference
annotation is used on a child reference of the target POJO, which means it is a forward reference that includes during the serialization process whereas @JsonBackReference
annotation is a backreference that omits during the serialization process, usually used in the corresponding child class.
Hence, The property annotated with @JsonBackReference
here, which is the Team
in the TeamUsers
, won't be serialized. That is why when you try to get all the users having Team
inside the TeamUsers
, it won't work. Also, if it did, it would violate the purpose of the annotations that they're used for, recursive access mapping.
If you want to fetch data in either way, you should use @JsonIgnoreProperties
instead of those two annotations. Change your entity classes as follows and you'll get your desired output.
In Team
class, set @JsonIgnoreProperties("team")
on the team_users
field to ignore mapping team
inside this field again to avoid recursive mapping. Change your Team
class to:
public class Team {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "TEAM_ID")
private Integer id;
@OneToMany(mappedBy = "team", cascade = CascadeType.ALL, orphanRemoval = true)
@JsonIgnoreProperties("team")
private Set<TeamUsers> team_users = new HashSet<>();
}
Similarly, in User
class, set @JsonIgnoreProperties("user")
on the team_users
field to ignore mapping user
inside this field again to avoid recursive mapping. Change your User
class to:
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
@JsonIgnoreProperties("user")
private Set<TeamUsers> team_users = new HashSet<>();
}
And finally, in TeamUsers
class, set @JsonIgnoreProperties("team_users")
on both the team
and user
field to ignore mapping team_users
inside these field again to avoid recursive mapping. Change your TeamUsers
class to:
public class TeamUsers {
@EmbeddedId
private TeamUserId id;
@ManyToOne
@MapsId("teamId")
@JoinColumn(name = "team_id")
@JsonIgnoreProperties("team_users")
private Team team;
@ManyToOne
@MapsId("userId")
@JoinColumn(name = "user_id")
@JsonIgnoreProperties("team_users")
private User user;
@Column(name = "active")
private int active;
}
Now you can fetch the data in either way without having recursive mapping.
Upvotes: 13