'Lombok - Hibernate @OneToOne in same class - StackOverFlowError

I'm working with 2 tables: Person and City. I have a @ManyToOne relationship which worked fine. (many persons can belong to one city). Then I needed to create a parent-child relationship. (one person can be parent of another person). The code:

@Entity
@Data
@Table(name="PERSON")
public class Person {

    @Id
    @Column(name="person_id")
    private int id;

    @OneToOne
    @JoinColumn(name = "parent_id")
    private Person parentPerson;

    @OneToOne(mappedBy = "parentPerson")
    private Person childPerson;

    public Person() {
    }

    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "city_id", nullable = false)
    private City city;
}


@Entity
@Data
@Table(name = "city")
public class City {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "city_id")
    private Integer cityId;
    
    [...]
}

This code compiles, I let hibernate to create the table and I can see the parent_id column. However, after I inserted a few rows and ran myRepository.findAll(), I'm getting the following:

java.lang.StackOverflowError
    at java.base/java.lang.Integer.toString(Integer.java:438)
    at java.base/java.lang.Integer.toString(Integer.java:1165)
    at java.base/java.lang.String.valueOf(String.java:2951)
    at package.City.toString(City.java:15)
    at java.base/java.lang.String.valueOf(String.java:2951)
    at package.Person.toString(Person.java:16)
at java.base/java.lang.String.valueOf(String.java:2951)
    at package.Person.toString(Person.java:16)
    at java.base/java.lang.String.valueOf(String.java:2951)
[...]
    at java.base/java.lang.String.valueOf(String.java:2951)
    at package.Person.toString(Person.java:16)
    at java.base/java.lang.String.valueOf(String.java:2951)

Even inspecting the result in debug, it was returning the StackOverFlow error, but the child-parent mappings were done correctly. Even though from parent I could inspect/expand the child, then expand the parent and so on...

The example with @OneToOne in the same class is taken from here. Any ideas on how I can solve the issue?



Solution 1:[1]

Thanks @Daniel Wosch and @dan1st for suggestions. Indeed, the generated toString from Lombok's @Data was the problem. Solution was to use @Getter, @Setter, @EqualsAndHashCode from Lombok and my own toString which didnt reference both parent and child. Just one of them and it's ok.

Solution 2:[2]

Another option would be adding the following annotation right after the Data annotation: @EqualsAndHashCode(callSuper = false,exclude="your relational properties") Just replace the value of exclude with your field.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 UnguruBulan
Solution 2 javatar