본문 바로가기
스프링 부트/Error-Log

entitygraph 사용시 주의할 점

by illlilillil 2022. 1. 18.

다중 엔티티 그래프를 사용할땐 주의할 점이 있습니다..

몰랐던 부분인데 JPA에서 Fetch join의 조건이 있었습니다.

  • ToOne 관계는 몇 개든 사용할 수 있다
  • ToMany 관계는 다중 그래프 관계에서 한 곳만 쓸 수 있다.

기존 코드에서는 ToMany 관계가 두 개 모두 되어 있어 이러한 에러를 만나게 되었습니다.

org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags: [com.ireland.ager.account.entity.Account.products, com.ireland.ager.product.entity.Product.urlList]
@NamedEntityGraph(
        name = "Account.withProductAndUrl",
        attributeNodes = {
                @NamedAttributeNode(value = "products", subgraph = "urlList")
        },
        subgraphs = @NamedSubgraph(name = "urlList", attributeNodes = @NamedAttributeNode("urlList"))
)
@Entity
@Getter
@Setter
@EqualsAndHashCode(of = "accountId", callSuper = false)
@NoArgsConstructor
@AllArgsConstructor
public class Account extends BaseEntity {
    @Id
    @GeneratedValue
    Long accountId;
    String accountEmail;
    String profileNickname;
    String userName;
    String profileImageUrl;
    String accessToken;
    String refreshToken;
    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "account")
    Set<Product> products = new HashSet<>();
}

해결 방법

첫번째로 단순히 이중 엔티티 그래프 사용을 중지하는 것입니다. 그러나 우리 프로젝트에서 꼭 필요한 로직이었기 때문에 이 부분을 포기할 수 없었습니다.

두번째로 List<Product>를 Set으로 바꾸는 작업입니다. Set은 리스트와 달리 중복을 허용하지 않기때문에 카테시안 곱이 발생하지 않게 됩니다. Set으로 바꿈으로 N+1문제도 해결하고 중복 데이터 문제도 함께 해결을 하게 되었습니다.

 

댓글