다중 엔티티 그래프를 사용할땐 주의할 점이 있습니다..
몰랐던 부분인데 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문제도 해결하고 중복 데이터 문제도 함께 해결을 하게 되었습니다.
'스프링 부트 > Error-Log' 카테고리의 다른 글
[Error-Log] ORA-01861: literal does not match format string (0) | 2022.08.25 |
---|---|
[Error-Log] MultipleBagFetchException 해결법 (0) | 2022.04.16 |
스프링 Java 8 LocalDateTime 직렬화 역직렬화 오류 해결 방법 (0) | 2022.02.05 |
[Error-Log] ConcurrentModificationException 해결법 (0) | 2022.02.04 |
스프링 레디스 Redis 에러 Creating Server TCP listening socket *:6379: bind: No error (0) | 2022.01.18 |
댓글