CODE SQUAD/FeedBack 정리

[Review] 2022/04/20 1차 PR (반찬 서비스)

샤아이인 2022. 4. 21.

 

이번 리뷰는 wooody 께서 해주셨다! 리뷰해주셔서 감사합니다 !!

 

1. 질문

팀원과 Spring Data Jdbc를 사용하던 도중, OneToMany 관계를 이용할 때 Map을 통해 저장하도록 하였었습니다.
Category : item = 1 : N 의 관계로 말이죠!

하지만 해당 Map을 이용할 경우 어그리게이트 루트에 해당되는 Category는 auto_increment가 잘 적용되지만,
item은 auto_increment가 정상작동하지 않았습니다.

혹시 Map을 사용할때는 id값을 직접 지정해줘야 하나요?

@Test
public void itemSaveTest() {
    // given
    Category mainCategory = new Category(CategoryType.MAIN);
    Item newItem = new Item("고기", "맛있는 고기", BigDecimal.valueOf(10000),
            10.0, Badge.EVENT, "풍성한 고기 반찬", 10, BigDecimal.valueOf(100), "html");
    
    // when
    mainCategory.saveItem(newItem); // item의 id가 null
    Category savedCategory = categoryRepository.save(mainCategory); // category는 id생성, but item의 아이디는??
  
    // then
    Category findCategory = categoryRepository.findById(savedCategory.getId()).get();
    List<Item> findItems = findCategory.getItems();
    Item findItem = findItems.get(0);
    assertThat(findItem.getTitle()).isEqualTo("고기");
}

public class Category {

    @Id
    private Long id; // 1L
    private CategoryType type;

    public Category(CategoryType type) {
        this.type = type;
    }

    @MappedCollection(idColumn = "category_id", keyColumn = "id")
    private Map<String, Item> items = new ConcurrentHashMap<>();

    public Long getId() {
        return id;
    }

    public List<Item> getItems() {
        return new ArrayList<>(items.values());
    }

    public void saveItem(Item item) {
        items.put(item.getId(), item);
    }
}

잘 작동하지않아 우선 List로 변경하여 처리하였습니다.

하긴 그렇긴 하다... 왜 Map을 쓰려 했을까? 나도 모르겠다.....

@MappedCollection의 원리 또한 정확하게 이해하지 못한 것 같다... 

 

2. 코드 리뷰

1. 데이터 초기화 Bean 에 대한 고찰

당장은 스크립트로 insert 해주기가 귀찮아 그냥 initDB 라는 Bean 을 만들어 사용하고 있었다.

해당 Bean을 @PostConstruct를 통해 매 실행마다 초기화 데이터를 삽입하도록 사용하고 있었다.

 

당연히 이 Bean은 개발단계에서만 사용할 것 이다!!

상식선에서 이정도는 당연하다! 배포 전에 까먹지 말고 제거 해야겠다!

 

2. Schema.sql 의 FK 검증

처음 drop table을 하는 단계에서 FK 때문에 Drop 이 되지 않는 문제를 해결하기 위해 스크립트 시작 지점에 다음과 같이 설정해 줬었다.

SET FOREIGN_KEY_CHECKS = 0;

이 부분을 제거하기 위해 DROP TABLE 의 순서를 조정하였다.

DROP TABLE IF EXISTS items;
DROP TABLE IF EXISTS category;
DROP TABLE IF EXISTS orders;
DROP TABLE IF EXISTS item_order;

각 Table 들의 의존성이 서로 연관되어 있기 때문에 에러가 발생했던 것 이다.

 

Category <- item 과 같이 카테고리 1개에 N개의 아이템이 1:N 으로 매핑이 되어있었다.

이러한 상황에서 Category를 먼저 지우려 하여 에러가 발생하였다. 이를 해결하기 위해 Item 부터 drop 하니 성공하였다.

 

3. 이미지를 위한 데이터 타입은?

이미지를 위한 링크가 어느정도 길어야함을 처음 알았다! 

VARCHAR(255) 로 변경해 주었다.

https://stackoverflow.com/questions/4444442/how-do-i-store-the-location-of-an-image-in-a-database

 

4. ControllerTest

원래 맨 처음 테스트를 작석할때부터 그냥 @SpringBootTest로 편하게 가기 위해 통합테스트를 생각했었다.

 

근데 이름이 CategoryControllerTest 였다...

이는 꼭 Slice 테스트를 진행하기 위한것 처럼 보인다. 

 

따라서 이름은 IntegrationTest 로 변경하여 통합 테스트임을 명시 하였다.

 

5. 테스트에도 기본 접근 제어가 추가하기

기본 테스트 서식 지정자를 추가하지 않았다. Private 로 변경해 주었다!

댓글