devYuraKim / devYuraKim/spring

example41 - StackOverflow caused by bidirectional association w/ @Data

Open
#3 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
CSS
Stars
2
Forks
1
PR merge metrics
No merged PRs in 30d

Description

cased by `Person.java` and `EazyClass.java`

------

In a bidirectional association in JPA/Hibernate, having two entities reference each other can potentially lead to a stack overflow error if not handled correctly, especially when using Lombok's `@Data` annotation. The `@Data` annotation generates `toString()`, `equals()`, and `hashCode()` methods, which can cause issues with bidirectional relationships.

Why the Stack Overflow Occurs
The stack overflow occurs because the generated `toString()`, `equals()`, and `hashCode()` methods can end up in an infinite loop. For example:

Entity A references Entity B.
Entity B references Entity A.
When `toString()` is called on Entity A, it calls `toString()` on Entity B, which in turn calls `toString()` on Entity A, and so on, leading to a stack overflow.

------

- Solutions

**1. Use @ToString.Exclude and @EqualsAndHashCode.Exclude**
By excluding the bidirectional field, you prevent the infinite loop in the toString(), equals(), and hashCode() methods.

`Person.java`
```
@ManyToOne(fetch = FetchType.LAZY, optional = true)
@JoinColumn(name = "class_id", referencedColumnName = "classId", nullable = true)
@JsonBackReference
@ToString.Exclude
@EqualsAndHashCode.Exclude
private EazyClass eazyClass;
```

`EazyClass.java`
```
@OneToMany(mappedBy = "eazyClass", cascade = CascadeType.PERSIST,targetEntity = Person.class)
@JsonManagedReference
@ToString.Exclude
@EqualsAndHashCode.Exclude
private Set persons;
```

**2. Manually Implement toString(), equals(), and hashCode()**

------

- Conclusion

When using bidirectional associations with Lombok's `@Data` annotation, it's crucial to prevent infinite recursion in the generated methods. You can achieve this by excluding the bidirectional fields from `toString()`, `equals()`, and `hashCode()` using `@ToString.Exclude` and `@EqualsAndHashCode.Exclude`, or by manually implementing these methods to avoid the recursion.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.