1. 문제 상황

- 결과 내용이 반복적으로 나옴

2. 원인

- 객체 간 순환 참조(circular reference)가 원인일 수 있음

- Product 객체가 Store 객체를 참조하고, Store 객체도 다시 Product 객체를 참조

3. 해결 방법

1) DTO 사용하기: 엔티티를 직접 반환하는 대신 Data Transfer Object (DTO)를 사용하여 API 응답을 구성

- DTO 클래스 정의

package com.zerobase.ecproject.dto;

import lombok.Data;

@Data
public class ProductDTO {
  private Long id;
  private String name;
  private String description;
  private Integer price;
  private String category;
  private Integer stockQuantity;
  private Long storeId;
}

- 엔티티를 DTO로 변환하는 메서드 구현 (ProductService)

  public ProductDTO convertToDTO(Product product) {
    ProductDTO dto = new ProductDTO();
    dto.setId(product.getId());
    dto.setName(product.getName());
    dto.setDescription(product.getDescription());
    dto.setPrice(product.getPrice());
    dto.setCategory(product.getCategory());
    dto.setStockQuantity(product.getStockQuantity());
    dto.setStoreId(product.getStore() != null ? product.getStore().getId() : null);
    return dto;
  }

- ProductController 수정, ProductDTO 객체를 Product 엔티티 객체로 변환, Product 엔티티를 ProductDTO 객체로 변환

@PostMapping("/{storeId}")
  public ResponseEntity<ProductDTO> createProduct(@RequestBody ProductDTO productDTO,
      @PathVariable Long storeId) {
    Product product = convertToEntity(productDTO);
    Product createdProduct = productService.createProduct(product, storeId);
    return ResponseEntity.ok(convertToDTO(createdProduct));
  }

  private Product convertToEntity(ProductDTO dto) {
    Product product = new Product();
    product.setName(dto.getName());
    product.setDescription(dto.getDescription());
    product.setPrice(dto.getPrice());
    product.setStockQuantity(dto.getStockQuantity());
    return product;
  }

  private ProductDTO convertToDTO(Product product) {
    ProductDTO dto = new ProductDTO();
    dto.setId(product.getId());
    dto.setName(product.getName());
    dto.setDescription(product.getDescription());
    dto.setPrice(product.getPrice());
    dto.setCategory(product.getCategory());
    dto.setStockQuantity(product.getStockQuantity());
    dto.setStoreId(product.getStore() != null ? product.getStore().getId() : null);
    return dto;
  }

- 문제 해결


2) Jackson 라이브러리 설정

- @JsonManagedReference와 @JsonBackReference 애노테이션을 사용하여 순환 참조를 관리

- @JsonIgnore를 사용하여 직렬화에서 특정 필드를 제외

3) Lombok의 @ToString.Exclude 사용

- @ToString 메서드에서 순환 참조가 발생하는 필드를 제외

- toString() 메서드 호출 시 순환 참조로 인한 문제를 방지

+ Recent posts