강의

멘토링

로드맵

인프런 커뮤니티 질문&답변

스프링초보님의 프로필 이미지
스프링초보

작성한 질문수

[JPA, QUERYDSL] entity 순환참조 문제 질문

작성

·

815

0

카테고리를 계단식 재귀 형태로 불러서 쓰고싶은데 해당 코드를 호출할 경우 영속성 문제로 조회가 제대로 되지 않습니다..

혹시 해당 문제에 대한 답을 알고계시면 답변 부탁드려요 ㅠ

 


// 오류 내용
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Handler dispatch failed: java.lang.StackOverflowError] with root cause

// 엔티티
@Entity
data class VocCategoryEntity(
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "cate_seq", nullable = false)
    var cateSeq: Long? = null,

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "parent_cate_seq")
    var parentCategory: VocCategoryEntity? = null,

    @OneToMany(
        mappedBy = "parentCategory",
        targetEntity = VocCategoryEntity::class
    )
    var childrenCategory: List<VocCategoryEntity>? = ArrayList()
)

// 리포지토리
query
.selectFrom(vocCategoryEntity)
.leftJoin(vocCategoryEntity.childrenCategory)
.fetchJoin()
.fetch()

답변 1

0

안녕하세요, 스프링초보님. entity 순환참조 문제로 인해 발생하는 영속성 문제에 대해 질문하셨군요.

해당 오류는 엔티티 간의 순환 참조로 인해 발생할 수 있습니다. 자식 카테고리가 부모 카테고리를 참조하고, 부모 카테고리가 다시 자식 카테고리를 참조하는 구조인데, 이렇게 순환 참조가 발생하면 영속성 컨텍스트에서 무한 루프로 인한 StackOverflowError가 발생할 수 있습니다.

JPA에서는 순환 참조 문제를 해결하기 위해 @JsonIgnore 어노테이션을 사용할 수 있습니다. 해당 어노테이션을 사용하면 JSON 직렬화 시에 해당 필드를 무시하도록 설정할 수 있습니다. 그러나 @JsonIgnore를 사용하면 양방향 연관관계에서 한쪽은 제외되어 조인이 되지 않는 이슈가 발생할 수 있습니다.

순환 참조 문제를 해결하는 또 다른 방법은 DTO(Data Transfer Object)를 사용하는 것입니다. 엔티티와 동일한 구조의 DTO를 만들어서 해당 DTO를 사용하여 데이터 조회 작업을 수행하는 것이 좋습니다. 엔티티와 DTO를 분리하여 사용하면 순환 참조 문제를 피할 수 있습니다.

만약 DTO를 사용하지 않고 엔티티 그대로 사용하고자 한다면, @JsonIgnore 어노테이션 대신 @JsonManagedReference@JsonBackReference 어노테이션을 사용하여 양방향 연관관계에서 한쪽을 참조하지 않도록 설정하는 방법도 있습니다.

이러한 방법들을 적절하게 사용하여 순환 참조 문제를 해결하시면 됩니다. 감사합니다.

간단한 예제를 제작해서 @JsonManagedReference@JsonBackReference를 사용해서 작성할경우 제대로 동작하는데 카테고리가 200~300개정도 되는 테이블에서 작성할경우 정상적으로 동작하지 않습니다 json 직렬화 작업시에 데이터가 많이꼬여있을경우 정상적으로 매핑이 불가능할까요? fk까지 동일하게 걸려있습니다

스프링초보님의 프로필 이미지
스프링초보

작성한 질문수

질문하기