I have entities in my project(based on Spring-Boot
Hibernate
):
@Entity
@Table(name = "user_account")
public class UserAccount {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@NotNull
@Column(name = "username")
private String userName;
@NotNull
@Column(name = "first_name")
private String firstName;
@NotNull
@Column(name = "last_name")
private String lastName;
@NotNull
@Column(name = "password")
private String password;
@CreationTimestamp
@Column(name = "birthday")
private LocalDateTime birthday;
@NotNull
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "role", referencedColumnName = "id")
private UserRole role;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "userAccount", cascade= CascadeType.ALL)
private Set<RentInfo> rents;
}
and
@Entity
@Table(name = "rent_info")
public class RentInfo {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@NotNull
@ManyToOne(cascade= CascadeType.ALL)
@JoinColumn(name="user_id")
private UserAccount userAccount;
@CreationTimestamp
@Column(name = "start_date")
private LocalDateTime startDate;
@CreationTimestamp
@Column(name = "end_date")
private LocalDateTime endDate;
@Column(name = "status")
private int status;
}
I want to create bi-directional one-to-many relation, when one user can have several rents and when we can select rents by concrete user_id, but something goes wrong
In response I get this:
{
"id": 1,
"userName": "[email protected]",
"firstName": "fName",
"lastName": "lName",
"password": "test",
"birthday": "2001-11-03T14:28:14",
"role": {
"name": "CLIENT"
},
"rents": [
{
"userAccount": {
"id": 1,
"userName": "[email protected]",
"firstName": "fName",
"lastName": "lName",
"password": "test",
"birthday": "2001-11-03T14:28:14",
"role": {
"name": "CLIENT"
},
"rents": [
{
"userAccount": {
"id": 1,
"userName": "[email protected]",
"firstName": "fName",
"lastName": "lName",
"password": "test",
"birthday": "2001-11-03T14:28:14",
"role": {
"name": "CLIENT"
}
.....
And this is unlimited and logically I have out of memory error. How can I fix this? what I'm doing wrong?
CodePudding user response:
You have two solutions :
- Use @JsonIgnore on the @ManyToOne
- Do NOT serialize your entities. Use DTOs instead and take care while mapping to avoid circular dependencies
CodePudding user response:
You can also use @JsonManagedReference
and @JsonBackReference
to solve this infinite recursion problem as follows:
@Entity
@Table(name = "user_account")
public class UserAccount {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@NotNull
@Column(name = "username")
private String userName;
@NotNull
@Column(name = "first_name")
private String firstName;
@NotNull
@Column(name = "last_name")
private String lastName;
@NotNull
@Column(name = "password")
private String password;
@CreationTimestamp
@Column(name = "birthday")
private LocalDateTime birthday;
@NotNull
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "role", referencedColumnName = "id")
private UserRole role;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "userAccount", cascade= CascadeType.ALL)
@JsonManagedReference
private Set<RentInfo> rents;
}
@Entity
@Table(name = "rent_info")
public class RentInfo {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@NotNull
@ManyToOne(cascade= CascadeType.ALL)
@JoinColumn(name="user_id")
@JsonBackReference
private UserAccount userAccount;
@CreationTimestamp
@Column(name = "start_date")
private LocalDateTime startDate;
@CreationTimestamp
@Column(name = "end_date")
private LocalDateTime endDate;
@Column(name = "status")
private int status;
}
Nevertheless, I would first map your entities to DTOs. However, you might as well need to use @JsonManagedReference
and @JsonBackReference
in these new DTO classes if you want all data to be available (one way to avoid this infinite recursion problem would be not mapping userAccount
in RentInfoDto
but you might not want that because you also want to serialize UserAccountDto
data).