Hibernate OneToMany java.lang.StackOverflowError
Circular dependency can originate from Lombok's toString()
autogenerated method, if you use @Data
complex annotation. To exclude your circular dependecy for a certain field:
@Entity
@Data
public class Team {
...
@ToString.Exclude
@ManyToOne
private League league;
}
I had a very similar issue. I was using Lombok's @Data
annotation on my model objects to auto-generate getters, setters, and other standard methods. I believe the toString()
method generated by Lombok introduced a circular dependency between my Team
and League
objects. When I tried to get the Set<teams> teams
from my League
object, I got a java.lang.StackOverflowError
because Spring was calling the toString method for logging purposes.
I resolved this by getting rid of Lombok's toString()
method. I replaced the @Data
annotation with Lombok's @Getter
and @Setter
annotations. That way I still could benefit from free getters and setters without getting the toString()
method.
I had this error because I was parsing a list of objects mapped on both sides @OneToMany
and @ManyToOne
to json using jackson which caused an infinite loop.
If you are in the same situation you can solve this by using @JsonManagedReference
and @JsonBackReference
annotations.
Definitions from API :
JsonManagedReference (https://fasterxml.github.io/jackson-annotations/javadoc/2.5/com/fasterxml/jackson/annotation/JsonManagedReference.html) :
Annotation used to indicate that annotated property is part of two-way linkage between fields; and that its role is "parent" (or "forward") link. Value type (class) of property must have a single compatible property annotated with JsonBackReference. Linkage is handled such that the property annotated with this annotation is handled normally (serialized normally, no special handling for deserialization); it is the matching back reference that requires special handling
JsonBackReference: (https://fasterxml.github.io/jackson-annotations/javadoc/2.5/com/fasterxml/jackson/annotation/JsonBackReference.html):
Annotation used to indicate that associated property is part of two-way linkage between fields; and that its role is "child" (or "back") link. Value type of the property must be a bean: it can not be a Collection, Map, Array or enumeration. Linkage is handled such that the property annotated with this annotation is not serialized; and during deserialization, its value is set to instance that has the "managed" (forward) link.
Example:
Owner.java:
@JsonManagedReference
@OneToMany(mappedBy = "owner", fetch = FetchType.EAGER)
Set<Car> cars;
Car.java:
@JsonBackReference
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "owner_id")
private Owner owner;
Another solution is to use @JsonIgnore
which will just set null to the field.
The only way it can throw an StackOverFlow is when your Team's League is accessed recursively....
Team to League to Team to League
I'm guessing there's some function trying to convert your objects into some other representation reflectively or recursively resulting in an infinite loop.