JAVA/Error

# JPA 연관관계 매핑 후 toString() 사용시, stackoverFlow Error 발생

skysoo1111 2017. 11. 23. 17:32

[에러]

Method threw 'java.lang.StackOverflowError' exception. Cannot evaluate 패키지.toString()

 

[발생 상황]

JPA 연관관계 매핑 후 toString() 선언시, StackOverflowError 발생한다.

 

[발생 원인]

ORM 프레임워크인 JPA를 사용하여 DB설계를 진행하다보면 단방향이 아닌 양방향 연관관계를 맺게된다.

이 때 관계를 맺은 두 엔티티가 서로 toString을 호출하면서 무한 반복되어 StackOverFlow 에러가 발생하는 경우가 있다.

 

 

[해결 방안1 - 롬복 미사용시]

org.apache.commons.lang.builder 패키지의 ToStringBuilder클래스를 이용한다.

 

 @Override
public String toString() {
    return ToStringBuilder
    .reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);

위와 같이 toString() 을 선언해주면 에러 해결

 

 

[해결 방안2 - 롬복 사용시 1]

exclude는 toString을 재정의 후 참조하는 객체를 지우는 것과 같은 효과

...
@ToString(exclude = "team")
public class Team { 
	
    @Id
    @GeneratedValue
    private Long id;
    private String teamName;
    @OneToMany(mappedBy = "user")
    private Set<User> users;
}

 

[해결 방안3 - 양방향 매핑의 상호 참조가 문제이니 두 객체 중 하나의 객체에서 직렬화를 진행하지 않으면 된다.]

@JsonManagedReference: 직렬화 함

@JsonBackRefrence : 직렬화 하지 않도록 막음(역직렬화 중에 해당 필드 값은 Managed 링크가 있는 인스턴스로 설정됨

...
@ToString
public class Team { 
	
    @Id
    @GeneratedValue
    private Long id;
    private String teamName;
    @OneToMany(mappedBy = "user")
    @JsonManagedReference
    private Set<User> users;
}
...
@ToString
public class User {
	
    @Id
    @GeneratedValue
    private Long id;
    private String userName;
    @ManyToOne
    @JsonBackReference
    private Team team;
}

 

 

참조글

[http://yellowh.tistory.com/135]