First I would like to explain what I am trying to achieve here. I am making an app that lets sports teams managers manager their games, practices and such. The idea is that person can play for more than one team. My code looks like this DomainUser.java holds information about a person, name, last name, email and such.
@Entity
@Table
@AllArgsConstructor
@NoArgsConstructor
@Setter
@Getter
@With
public class DomainUser {
@Id
@Column(columnDefinition = "VARCHAR(36)")
@Type(type="org.hibernate.type.UUIDCharType")
@GeneratedValue
private UUID id;
@Column
private String firebaseId;
@Column
private String email;
@Column
private String phoneNumber;
@Column
private String name;
@Column
private String lastName;
@Column
private Date birthDay;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private List<TeamMember> teamMembers;
private Date created;
private Date updated;
@PrePersist
protected void onCreate() {
created = new Date();
}
@PreUpdate
protected void onUpdate() {
updated = new Date();
}
}
As you can see this object also holds TeamMembers which are, players, managers or just owners. TeamMember.java
@Table(name = "teamMember")
@Entity
@AllArgsConstructor
@NoArgsConstructor
@Data
@With
public class TeamMember {
@Id
@Column(columnDefinition = "VARCHAR(36)")
@Type(type="org.hibernate.type.UUIDCharType")
@With(AccessLevel.NONE)
@Setter(AccessLevel.NONE)
@GeneratedValue
private UUID id;
@JsonBackReference
@JsonIgnore
@ManyToOne(cascade = CascadeType.ALL)
private DomainUser domainUser;
@JsonBackReference
@JsonIgnore
@ManyToOne(cascade = CascadeType.ALL)
private Team team;
@Column(columnDefinition="tinyint(1) default 0")
private Boolean isOwner;
@Column(columnDefinition="tinyint(1) default 0")
private Boolean isManager;
@Column(columnDefinition="tinyint(1) default 1")
private Boolean isPlayer;
private Date created;
private Date updated;
@PrePersist
protected void onCreate() {
created = new Date();
}
@PreUpdate
protected void onUpdate() {
updated = new Date();
}
}
Which holds class Team.
@Table(name = "team")
@Entity
@AllArgsConstructor
@NoArgsConstructor
@Data
@With
public class Team {
@Id
@Column(columnDefinition = "VARCHAR(36)")
@Type(type="org.hibernate.type.UUIDCharType")
@GeneratedValue
private UUID id;
@Column
private String teamName;
@OneToMany(cascade = CascadeType.ALL)
@JsonManagedReference
private List<TeamMember> teamMembers;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "invitation_id", referencedColumnName = "id")
private InvitationLink invitationLink;
@Column
private double payPerPractice;
@Column
private String season;
@Column(columnDefinition="tinyint(1) default 1")
private boolean activeSeason;
@Column
private double payPerGame;
private Date created;
private Date updated;
@PrePersist
protected void onCreate() {
created = new Date();
}
@PreUpdate
protected void onUpdate() {
updated = new Date();
}
}
Whenever i try to call any of these three repositories i get error that looks something like this.
java.lang.StackOverflowError: null
at com.kunal52.springandfirebaseauth.domain.TeamMember.toString(TeamMember.java:18) ~[classes/:na]
at java.base/java.lang.String.valueOf(String.java:3367) ~[na:na]
at java.base/java.lang.StringBuilder.append(StringBuilder.java:167) ~[na:na]
at java.base/java.util.AbstractCollection.toString(AbstractCollection.java:457) ~[na:na]
at org.hibernate.collection.internal.PersistentBag.toString(PersistentBag.java:622) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
at java.base/java.lang.StringConcatHelper.stringOf(StringConcatHelper.java:429) ~[na:na]
at com.kunal52.springandfirebaseauth.domain.Team.toString(Team.java:19) ~[classes/:na]
at java.base/java.lang.StringConcatHelper.stringOf(StringConcatHelper.java:429) ~[na:na]
at com.kunal52.springandfirebaseauth.domain.TeamMember.toString(TeamMember.java:18) ~[classes/:na]
Im concerned that my code is wrong because i get these errors and my databse tables look like following.
Could someone give me any insights on this pleas?
CodePudding user response:
The toString method (generated by Lombok) has a circular reference and cannot
TeamMember contains an object of type Team, and this refers to TeamMember, etc...
One way would be to exclude some property from the @ToString that Lombok generates. could you use @ToString.Exclude
@Table(name = "teamMember")
@Entity
@AllArgsConstructor
@NoArgsConstructor
@Data
@With
@ToString
public class TeamMember {
@JsonBackReference
@JsonIgnore
@ToString.Exclude
@ManyToOne(cascade = CascadeType.ALL)
private Team team;
}
@Table(name = "team")
@Entity
@AllArgsConstructor
@NoArgsConstructor
@Data
@With
@ToString
public class Team {
@OneToMany(cascade = CascadeType.ALL)
@JsonManagedReference]
@ToString.Exclude
private List<TeamMember> teamMembers;
}