[Java JPA] N:1 참조 (Lombok 순환참조)

전재준·2021년 12월 12일
0

Java

목록 보기
5/15

유저(User), 이미지(Table) 1:N 연관관계

1. JPA 공부중 User 테이블과 Image 테이블을 만든 후 두 테이블의 연관관계

  • 다대일(N:1)
  • 한명의 User는 여러개의 Image를 등록할 수 있다.
  • 여러개의 Image는 한명의 User가 등록할 수 있다

Image Entity

User Entity

2. 두 테이블 사이의 연관관계의 주인은 외래키를 가진 Image테이블이 가진다.

  • 데이터베이스는 N쪽이 외래 키를 갖는다.
  • 외래 키가 있는 곳을 주인으로 정해라. @JoinColumn이 있는 쪽.
  • 주인이 아닌쪽은 읽기만 가능
  • mappedBy 연관관계의 주인이 아님, 그러므로 테이블에 컬럼을 생성하지않음
  • User Select 할때 UserId로 등록되어있는 image를 가져옴
  • fetch default LAZY -> SELECT 할떄는 안가져옴 그대신 getImages를 하면 가져옴
  • fetch EAGER -> select 할 때 전부가져옴
  • 실무에서는 다 LAZY로 쓰자. 즉시 로딩 사용하지 말자(성능 이슈).

순환참조

3. 해당관계로 테이블 생성 후 User Object 를 호출하니 java.lang.StackOverflowError: null 에러가 발생했다. 오타가 났는지 디버그를 찍어봐도 뭐가 문제인지 찾지 못해서 구글링을 한 결과 Lombok에 @ToString에 문제가 있었다.

User 를 호출하면 User toString이 호출되면서 Stack에 메모리가 쌓이고 연관관계를 정의했으므로 Image에 toString이 호출되면서 Stack 메모리에 쌓이고 Image가 User를 호출하면서 Userd에 toString을 계속참조하면서 무한참조에 걸리고 Stack메모리가 풀로차면서 결국 StackOverflowError에러가 발생하게 된다.

4.해결방안

  • Lombok 에 @Data 안에는 @ToString이 있으므로 get,set을 사용할거라면
    @Getter
    @Setter 을 사용하자
  • Object 의 toString을 재정의후 참조하는 객체를 지운다.
  • @JsonIgnoreProperties({"user"}) 어노테이션을 이용한다.

일하면서 얼핏 Lombok을 남발하지 말라고 들었는데 직접 경험해보니 왜 그런지 깨닫는 에러였다.

JPA를 사용하면 객체 간의 또 다른 순환 참조가 발생하는 경우가 있을 수도 있으니 더 공부해야겠다.


참고자료
https://www.easyupclass.com/course/218/about

0개의 댓글

관련 채용 정보