Troubleshooting: 무엇이 문제였는가?/본캠프 3주 차: 일정 관리 앱 만들기

2단계: "꿈쩍 안 하는 수정일과 얼음땡!"

writingforever162 2024. 12. 6. 14:56

[문제]

분명히 일정을 수정했는데, createdDate와 updatedDate가 동일했다. 다시 말해 수정한 날짜에 해당하는 updatedDate가 그대로였다. 이번 문제는 튜터님과 함께 디버깅(debugging)을 진행하며 원인을 찾아냈다.

 

[원인]

위의 사진처럼 디버깅을 몇 번 해본 결과, createdDate와 updatedDate 설정에 원인이 있다고 추측했다.

package com.spring.weekthree.entity;

import lombok.Getter;
import lombok.Setter;

import java.time.LocalDateTime;

@Getter
public class Plan {
    // [1] 속성
    @Setter
    private Long id;
    private String name;
    private String password;
    private LocalDateTime plannedDate;
    private String title;
    private String task;
    private LocalDateTime createdDate;
    private LocalDateTime updatedDate;

    /**
     * [2] 생성자
     * @param name : 사용자 이름
     * @param password : 사용자 비밀번호
     * @param plannedDate : 사용자가 입력한 일정 날짜
     * @param title : 사용자가 입력한 일정의 제목
     * @param task : 사용자가 입력한 일정의 상세 정보
     */
    public Plan(
            String name,
            String password,
            LocalDateTime plannedDate,
            String title,
            String task
    ) {
        this.name = name;
        this.password = password;
        this.plannedDate = plannedDate;
        this.title = title;
        this.task = task;

        this.createdDate = LocalDateTime.now();
        this.updatedDate = LocalDateTime.now();
    }
    // [3] 기능
    public void edit (
            String name,
            LocalDateTime plannedDate,
            String title,
            String task
    ) {
        this.name = name;
        this.plannedDate = plannedDate;
        this.title = title;
        this.task = task;

        LocalDateTime now = LocalDateTime.now();
        this.updatedDate = now;
        /*
        [수정 전]
        this.updatedDate = LocalDateTime.now();
        [수정 후]
        LocalDateTime now = LocalDateTime.now();
        this.updatedDate = now;
         */
    }
}

우선 엔티티(entity)에 해당하는 Plan 클래스(class)에서 별도로 변수 now에 값을 저장하니까 해결이 되긴 했다. 이때 한 가지 의문이 들었다.

 

'레이어(layer) 사이는 엔티티가 아니라 DTO(Data Transfer Object)가 오가는데?'

 

현재 생성한 DTO 중 RequestDTO는 클라이언트(client)가 보내는 정보였으므로 ResponseDTO에 해당하는 클래스를 살펴봤다. 그랬더니….

package com.spring.weekthree.dto;

import com.spring.weekthree.entity.Plan;
import lombok.Getter;

import java.time.LocalDateTime;

@Getter
public class PlanResponseDto {
    // [1] 속성
    private long id;
    private String name;
    private LocalDateTime plannedDate;
    private String title;
    private String task;

    private LocalDateTime createdDate;
    private LocalDateTime UpdatedDate;
    // 이 와중에 대문자로 쓰였다. 마찬가지로 수정해야 한다.
    
    // [2] 생성자
    public PlanResponseDto(Plan plan) {
        this.id = plan.getId();
        this.name = plan.getName();
        this.plannedDate = plan.getPlannedDate();
        this.title = plan.getTitle();
        this.task = plan.getTask();

        this.createdDate = plan.getCreatedDate();
        this.UpdatedDate = plan.getCreatedDate();
        /*
        [오답] this.UpdatedDate = plan.getCreatedDate();
        [정답] this.updatedDate = plan.getUpdatedDate();
         */
    }
    // [3] 기능
}

가지는 여름과 가을이 제철이라는데 겨울에도 정말 🍆🍆했다. 레이어(layer) 사이를 왔다 갔다 하면서 코드를 쓰다가 이런 어처구니없는 실수를 낸 듯했다. 어쨌든 원인은 아주 확실하게 찾아냈다.

 

[해결]

package com.spring.weekthree.dto;

import com.spring.weekthree.entity.Plan;
import lombok.Getter;

import java.time.LocalDateTime;

@Getter
public class PlanResponseDto {
    // [1] 속성
    private long id;
    private String name;
    private LocalDateTime plannedDate;
    private String title;
    private String task;

    private LocalDateTime createdDate;
    private LocalDateTime updatedDate;

    // [2] 생성자
    public PlanResponseDto(Plan plan) {
        this.id = plan.getId();
        this.name = plan.getName();
        this.plannedDate = plan.getPlannedDate();
        this.title = plan.getTitle();
        this.task = plan.getTask();

        this.createdDate = plan.getCreatedDate();
        this.updatedDate = plan.getUpdatedDate();
        /*
        [수정 전] this.UpdatedDate = plan.getCreatedDate();
        [수정 후] this.updatedDate = plan.getUpdatedDate();
         */
    }
    // [3] 기능
}

이번 개인 프로젝트 때도 트러블슈팅(Troubleshooting) 분량이 풍년일 듯한 직감에 눈이 질끈 감겼지만, 팀 프로젝트를 하기 전에 이런 실수를 저질러서 차라리 다행이다 싶기도 하고, 계산기 만들기 프로젝트를 진행할 때보다 원인을 추측하는 감이 좀 좋아진 듯하다. CRUD 중 D(Delete) 기능을 구현하기 전에 원인과 해결 방법을 확실하게 찾아서 기분이 좋다.