🌿SPRING/🌱연습[SPRING]

[SPRING] 모임 태그 - 태그 수정하기 (2) + bug fix

디카페인라떼 2022. 9. 28. 17:24

2022.09.28 - [SPRING/🌱연습[SPRING]] - [SPRING] 모임 생성 시 태그 같이 넣기

 

[SPRING] 모임 생성 시 태그 같이 넣기

기본 CRUD를 다 만들고나서 태그기능도 있으면 좋을 것 같아서 추가하려다가 삽질을 엄청했다. 쉽게 생각했지만 역시 세상은 녹록치 않았다... 모임 (게시글) 생성 시에 이미 DB에 있는 태그들을

wearegolden.tistory.com

이어서 생성시에 넣었으니 수정 시에 같이 수정도 되어야 한다고 생각했다

 

일단 생각했던 로직은

 1) 기존에 저장된 Tag를 모두 DB에서 지워주고 수정된 태그들만 다시 저장을 해주자! 

=> 로직이 간단해지지만 불필요한 성능낭비

 2) 기존에 저장된 Tag와 수정된 Tag를 비교해서 동일한 Tag는 그대로, 기존에는 있지만 수정된 Tag에는 없는 건 DB에서 삭제, 기존에 없지만 새로 수정된 Tag는 DB에 저장

=> 생각만해도 머리가 아파옴

 

그래도 이왕하는 거 제대로 해보자 싶어서 2번으로..^^..... 


Entity 설정이나 Dto는 생성시에 이미 했기때문에 로직만 잘짜면 된다 ^^! 

Meeting Update Service
//모임 수정
@Transactional
public void updateMeeting(Long meetingId, MeetingRequestDto requestDto, Member member) {
  //해당 모임 찾기
  Meeting meeting = meetingRepository.findById(meetingId)
      .orElseThrow(() -> new CustomErrorException(ErrorCode.NOT_FOUND_MEETING));

  //모임장과 같은 유저인지 확인하기
  if (meeting.isWrittenBy(member)) {

--------------------------------------------------------------------------------------------------
    // 태그, 이미지 외 수정
    meeting.update(requestDto);

    // 기존 태그와 비교
    Set<MeetingTagConnection> oldMeetingTagConnectionList = meeting.getMeetingTagConnectionList();

    // 새로운 tag id 리스트
    List<Long> newTagIdList = requestDto.getTagIds();

    // 기존 태그 id list
    List<Long> oldMeetingTagConnectionIdList = new ArrayList<>();
    for(MeetingTagConnection meetingTagConnection : oldMeetingTagConnectionList){
      oldMeetingTagConnectionIdList.add(meetingTagConnection.getId());
    }

    // 2중 for문을 사용하여서 비교
    for (MeetingTagConnection oldMeetingTagConnection : oldMeetingTagConnectionList) {
      for (Long newMeetingTagId : newTagMeetingIdList) {
        // 기존 태그 id 와 새로운 태그 id 가 같다면 => 같은 id는 남겨둬야함 
        if (oldMeetingTagConnection.getTagMeeting().getId().equals(newMeetingTagId)) {
                  
          // newMeetingTagIdList에 남아 있는 건 추가할 태그 (남길 id는 삭제)
          newTagMeetingIdList.remove(newMeetingTagId);

          // oldMeetingTagIdList에 남아 있는 건 삭제할 태그(남길 id는 삭제)
          oldMeetingTagConnectionIdList.remove(oldMeetingTagConnection.getId());
        }}}


    // 삭제
    //for문을 통해서 기존 id List중 삭제할 id만 남은 List에서 id들을 빼내서
    for (Long oldMeetingTagId : oldMeetingTagConnectionIdList){
      //아래에 만든 메소드로 TagId로 MeetingTagConnection을 찾아서
      MeetingTagConnection deleteMeetingTagConnection = findTagId(oldMeetingTagConnectionList, oldMeetingTagId);
      //기존에 존재하던 객체면 삭제해준다! DB에서도 삭제는 필수!
      if(deleteMeetingTagConnection != null){
        oldMeetingTagConnectionList.remove(deleteMeetingTagConnection);
        meetingTagConnectionRepository.delete(deleteMeetingTagConnection);
      }}

    // 추가
    //새로 추가할 TagId 들을 꺼낸 뒤
    for (Long newMeetingTagId : newTagMeetingIdList){
    // 해당 태그들을 찾아내고
      Tag tag
          = tagRepository.findById(newMeetingTagId)
          .orElseThrow(() -> new CustomErrorException(ErrorCode.ENTITY_NOT_FOUND));
      // 찾아낸 태그로 MeetingTagConnection 객체를 생성해서 저장해준다! 
      MeetingTagConnection meetingTagConnection = new MeetingTagConnection(meeting, tagMeeting);
      meetingTagConnection = meetingTagConnectionRepository.save(meetingTagConnection);
      oldMeetingTagConnectionList.add(meetingTagConnection);
    }
    // 위에 저장된 리스트를 meeting에도 저장해준다.
    meeting.setMeetingTagConnectionList(oldMeetingTagConnectionList);
----------------------------------------------------------------------------------------------------------------
  } else {
    throw new CustomErrorException(ErrorCode.NOT_ADMIN_OF_MEETING);
  }
}

👉 빡쎈 로직... 굉장히 헷갈렸다..

 

  • MeetingTagConnection 에서 TagId로 객체를 찾는 메소드를 만들어 준다 
    • JPA Repository에서 찾기가 까다로워서 그냥 메소드를 만들어줬다
private MeetingTagConnection findTagId(
    Set<MeetingTagConnection> meetingTagConnectionList, Long meetingTagConnectionId) {
  for (MeetingTagConnection meetingTagConnection : meetingTagConnectionList){
    if(meetingTagConnection.getId().equals(meetingTagConnectionId)){
      return meetingTagConnection;
    }
  }
  return null;
}

👉 리스트와 아이디를 넣어주면 리스트에서 객체를 꺼내서

👉객체의 아이디와 매개변수로 받은 아이디가 같은 객체를 출력해준다 

 


Postman API Test

👉 기존 모임 

  • 모임 수정시

👉에러 없이 수정 되었다는 메세지가 뜨고

 

👉 모임 조회시 잘 변경된 걸 확인할 수 있다.

 

 

 


220930 
  • 오늘 모임 수정 부분을 작동해보니 태그가 기존과 완전히 일치할때에는 에러가 떴다.

  • 디버깅을 해보니 tag에 null값이 들어갔다.

👉 기존 코드

  • 동일한 태그는 추가할 태그 목록에서 뺐었는데 그 과정에서 전체가 동일할 시에는 모두 remove 가 되기 때문에 null값이 들어갔다

 

👉 수정코드

  • 새로 받는 태그id 리스트와
  • 기존 태그id를 비교하여 
  • 조건문을 추가해주었다.
  • 이제 두 id 리스트가 같다면 = 기존과 전체 동일하다면 해당 로직을 타지 않고 그대로 출력이 된다.