• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    해결됨

@PostMapping으로 등록 시 파라미터 안에 List 질문입니다.

22.12.11 17:51 작성 22.12.11 21:08 수정 조회수 548

1

안녕하세요

강의 완강 후 따로 프로젝트를 만들어 보던 중 궁금한 게 생겨서 질문 드립니다.

 

PostMapping으로 등록할 때 CreateRequest라는 별도의 클래스를 만들어 주어서 파라미터로 받았는데

 

이 CreateRequest안에 List를 받아야 할 경우가 있다면 어떻게 해줘야 하는지 잘 모르겠습니다.

 

Product 클래스 입니다.

Module 클래스 입니다.

하나의 Product에 여러 개의 Module이 들어갈 수 있기 때문에

ProductModule 클래스를 만들어줬습니다.

이러한 경우에서

Product를 등록할 때

아래와 같이 넘겨주고 싶으면

CreateProductRequest 에서 List를 어떤식으로 받아줘야 하나요?

 

아래와 같이 해봤는데 잘 안되는 것 같아서요...

답변 1

답변을 작성해보세요.

0

y2gcoder님의 프로필

y2gcoder

2022.12.12

안녕하세요. gnstjrdlsla님, 공식 서포터즈 y2gcoder입니다.

먼저 살펴봤을 때,

image

여기서 List<ProductModule> 로 타입을 받으셨습니다.

그러나 ProductModule 클래스를 보면

moduleCode라는 이름을 가진 필드가 보이지 않습니다.

productModuleCode 필드의 이름을 moduleCode로 바꿔서 시도해보시길 추천드립니다.

그리고 개인적으로는 엔티티인 ProductModule 을 요청으로 바로 받기보다는 request 클래스를 만든 것처럼 list 안의 타입도 dto로 만들어서 받기를 추천드리겠습니다.


감사합니다.

안녕하세요

답변 감사합니다.

제가 질문에 대한 설명이 많이 부족했던 것 같습니다.

궁극적으로 제가 원하는 테이블의 모양은 대략적으로 아래와 같습니다.

image

저는 Product 테이블에 데이터를 등록할 때

Module 테이블에 있는 데이터들을 List로 골라서

Product_Module테이블도 등록되게 하고 싶은데

설계 자체가 잘 못된 것일까요?

y2gcoder님의 프로필

y2gcoder

2022.12.13

요구사항에 대해 정확히 알지는 못하지만 제가 드렸던 설명과 더불어 들어주시면 감사하겠습니다.

추가로 설명해주신 부분을 보고 이전 코드들과 같이 생각해봤을 때, Module들은 이미 DB에 저장되어 있다면 moduleCode들만 받아서 (이것도 추가적인 요구사항이 없다면 그냥 dto로 moduleCode들만 받으면 될 것 같습니다.) product와 함께 productModule 을 만들어주면 될 것 같습니다.

만약 Module들도 같이 저장해줘야 한다면 위의 과정에서 module을 저장해주는 부분도 추가해야 할 것 같습니다.

안녕하세요.

제가 답변 알림을 놓쳐서 확인을 이제야 했네요.

 

말씀해주신 설명 감사히 잘 봤습니다.

제가 실력이 부족해서 막히는 부분이 있어서요...

 

우선 Module들은 이미 DB에 저장돼있는 게 맞습니다.

따라서 moduleCode들만 List로 받아서 product를 등록할 때 productModule테이블도 함께 등록되게 하라고 말씀해주신 게 맞는지?

제가 맞게 이해한 건지 궁금합니다.

 

두 번째로 CreateProductRequest 안에 productModule로 바로 받기 보단 dto로 만들어서 받으라고 해주셨는데

image

image요런 moduleCode만 필드로 있는 Dto를 따로 생성해서 받으라고 하시는 게 맞나요?

이게 맞다면

Controller 부분에서 Product를 등록할 때

image위에 사진처럼

name 은 reqest의 name

explanation은 request의 explanation으로 받으면 되는데

productModuleList 같은 경우는 Set 해줄 때 request의 moduleDtoList로 하면 당연히 타입이 안 맞는데 요 부분을 어떻게 해결해야 할지 잘 모르겠습니다.

y2gcoder님의 프로필

y2gcoder

2022.12.22

따라서 moduleCode들만 List로 받아서 product를 등록할 때 productModule테이블도 함께 등록되게 하라고 말씀해주신 게 맞는지?

맞습니다 :)

 

dto를 entity로 변환하는 작업은 필요합니다. moduleCode는 있으니까 해당 모듈을 불러와서 저장하면 되지 않을까 합니다.

 

 

제가 dto를 entity로 변환하는 작업을 잘못하고 있는 것 같아서 질문 드립니다.

image

저는 List로 들어오는 ModuleDto를 ProductModule로 변환해 주기 위해

35 ~ 41 라인을 작성했습니다.

 

그리고 아래와 같이 Postman 으로 send해보니

image

아래와 같이 moduleCode들이 들어온 것을 확인했지만

image

41번 라인을 찍어봤을 때

productModuleList: [ProductModule(productModuleCode=null, product=null, module=null), ProductModule(productModuleCode=null, product=null, module=null), ProductModule(productModuleCode=null, product=null, module=null)]

위와 같이 NULL 값이 들어가더라구요...

 

제 생각에 38~41번 라인 dto를 entity로 변환하는 과정에서 제가 잘못하고 있는 것 같은데

조언 좀 부탁 드립니다 ㅜㅜㅜ

 

그리고 한 가지 더 궁금한 게 있습니다.

ProductMoudle DB에는

시퀀스 값으로 자동증가되는 productModuleCode,

product_code, module_code 3개의 컬럼이 있는데

그러면 request할 때 module_code만 값을 넣어주는 게 아니라

product_code도 넣어줘야 하지 않나요?

y2gcoder님의 프로필

y2gcoder

2022.12.26

제 생각에 38~41번 라인 dto를 entity로 변환하는 과정에서 제가 잘못하고 있는 것 같은데

조언 좀 부탁 드립니다 ㅜㅜㅜ

이 부분 코드를 보시면

List<ProductModule> productModuleList = moduleDtoList.stream()
    .map(moduleDto -> new ProductModule())  // 여기서 moduleCode를 넣어 ProductModule 객체를 만들어주셔야 합니다!
    .collect(Collectors.toList());

이렇게 해줘야 할 것 같습니다. 그런데 사실 이런 방식보다도 제 개인적인 생각으로는 moduleDtoList로 DB에서 moduleList를 불러오는 게 더 나을 것 같습니다.

그리고 한 가지 더 궁금한 게 있습니다.

ProductMoudle DB에는

시퀀스 값으로 자동증가되는 productModuleCode,

product_code, module_code 3개의 컬럼이 있는데

그러면 request할 때 module_code만 값을 넣어주는 게 아니라

product_code도 넣어줘야 하지 않나요?

그리고 해당 부분은 당연히 말씀하신 게 맞습니다. 그러려면 먼저 product를 persist해서 product_code를 만들어야겠지요?

차근차근 고민해보시고 해보시면 하실 수 있습니다 :)

파이팅!

답변 감사합니다.

moduleDtoList로 DB에서 moduleList를 불러오는 방식이 더 나을 것 같다고 해주셨는데

부끄럽지만 저의 짧은 지식으로는 이해가 잘 안돼서요..

moduleDtoList를 파라미터로 받아서 moduleList를 불러오는 쿼리문을 만들어 주시라는 뜻인가요?

y2gcoder님의 프로필

y2gcoder

2022.12.26

moduleDto로 받은 moduleCode들이 확실하다면 그냥 해당 dto에서의 moduleCode들을 그대로 이용해도 되나, 그렇지 않다면 DB에서 moduleCode들로 Module 들을 가져와야한다는 취지에서 말씀드렸습니다!

+추가로 성능적으로 고민이 되신다면 JpaRepository의 getReferenceById() 를 이용해서 프록시를 불러오실 수 있습니다. 이 부분은 먼저 윗 부분을 해보시고 적용해보시길 권해드립니다.

감사합니다, 이해가 너무 잘 되네요.

 

말씀해 주신 대로 생성자 주입을 이용한 방식을 먼저 적용해봤습니다.

값은 제가 원하는 대로 잘 들어가는데 아래와 같이 주입 해주는 게 맞는 방식인지 궁금해서 여쭤 봅니다.

image

image

y2gcoder님의 프로필

y2gcoder

2022.12.26

멋집니다 :)

일단 이대로 진행하시되,

나중에는 Jpa Entity들에서는 setter를 없애는 방향으로 리팩토링 해보시면 더 많은 도움이 되실 것 같습니다!

감사합니다, 도움 정말 많이 됐습니다!

y2gcoder님의 프로필

y2gcoder

2022.12.27

감사합니다~ 즐거운 개발하시길!