어제 도전 과제 6단계를 해내길 정말 잘했다! 왜냐하면 아침부터 추가로 구현해야 하는 부분이 생겼기 때문이다! 바로 소프트 딜리트(Soft Delete), 일명 논리 삭제였다! 논리 삭제는 이름에서 알 수 있듯이 클라이언트(client)에게는 삭제되었다고 보여주고, 데이터베이스에는 그 정보가 그대로 있는, 말 그대로 '삭제된 척하는 삭제'였다.
필수 과제 2단계부터 @ManyToOne 어노테이션(annotation)을 써서 단방향 연관관계를 설정해야 했는데, 그 상태에서 하드 딜리트(hard delete)를, 일명 물리 삭제를 하려고 하면 오류 메시지를 마주했다. 이 상태에서 정보를 진짜로 지우고 싶다면 cascade 옵션을 설정해야 하는데, 잠시 고민했다가 논리 삭제를 골랐다. 일단 정보 자체가 소중한 자산이고, 법적으로 몇 개월 보관해야 하는 상황도 같이 떠올랐기 때문이다. 만약 비밀번호 암호화를 어제 해놓지 않았다면, 도전 과제 7단계와 8단계는 시도할 엄두조차 못 냈을 거다.
그렇다면 과제를 끝낸 지금은 기분이 어떤가?
자바(Java)로 계산기를 만들 때만 해도 필수 과제 해내기에도 벅찼는데, 도전 과제 마지막 단계인 페이지네이션(Pagination)에 성공했을 땐 아주 찰나이긴 했으나 솔직히 좀 감격스러웠다. 구글링에 챗GPT를 그 어느 때보다 많이 활용하고, 문제가 생겼다 싶으면 튜터님께 달려가는 일이 일상이긴 했지만.
감동의 물결이 살짝 일렁이긴 했으나, 아직 보람을 느끼기엔 이르다. 논리 삭제를 이전 단계에도 반영해야 하고, 튜터님들이 계신 시간에 최대한 궁금증을 해결하려고 문서 작성을 학습 시간 전후로 밀렸더니 쓸거리가 산더미처럼 쌓였다! 특히 데이터베이스(database) 구조가 바뀌는 시점에 맞춰 깃허브(GitHub)에 새로 브랜치(branch)를 생성했기 때문에, 리드미(README)만 다섯 편이다! 'feat/level-seven, eight' 브랜치에 쓴 리드미를 복사해서 붙여 넣은 다음 수정하는 식으로 진행하긴 할 테지만, 임시 저장한 트러블슈팅(troubleshooting)까지 생각하면 정말, 참…….
package com.example.plan.member7.entity;
import com.example.plan.base.BaseEntity;
import jakarta.persistence.*;
import lombok.Getter;
import org.hibernate.annotations.Comment;
@Getter
@Entity
@Table(name = "members7")
public class Member extends BaseEntity {
// 속성
@Comment("사용자 식별자")
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(columnDefinition = "BIGINT")
private Long id;
@Comment("사용자 이름")
@Column(
name = "username"
, nullable = false
, columnDefinition = "VARCHAR(32)"
)
private String username;
@Comment("사용자 이메일")
@Column(
name = "email"
, nullable = false
, unique = true
, columnDefinition = "VARCHAR(128)"
)
private String email;
@Comment("사용자 비밀번호")
@Column(
name = "password"
, nullable = false
, columnDefinition = "VARCHAR(255)"
)
private String password;
// 기본 생성자
public Member() {
}
/**
* 생성자
*
* @param username : 사용자의 이름
* @param email : 사용자의 이메일
* @param password : 사용자의 비밀번호
*/
public Member(
String username
, String email
, String password
) {
this.username = username;
this.email = email;
this.password = password;
}
/**
* 기능
* 사용자의 이름과 이메일 수정 (UPDATE - PUT)
*
* @param username : 수정하려는 사용자의 이름
* @param email : 수정하려는 사용자의 이메일
*/
public void update(
String username
, String email
) {
this.username = username;
this.email = email;
}
}
주석까지 포함해서 이렇게까지 글을 많이 쓴 적이 있었나, 종종 물음표가 둥실 떠오르곤 한다.
"여기서 조심하지 않으면 500번 오류 메시지를 보실 거예요. 경험담이랍니다.'
오늘 팀원분에게 로그인 기능 구현을 간단히 설명하다가 '진짜 다양한 오류를 냈구나' 싶었다. 그렇게 오류를 낸 덕분에 이번에 도전 과제를 모두 도전할 수 있지 않았을까 싶기도 하고.
한 줌의 아쉬움도 남지 않도록 내일 제출 마감 전까지 여태 해낸 과제를 공들여 다듬어야겠다.
[24.12.19 할 일 목록]
🥇 도전 과제 6단계: 비밀번호 암호화 ▶ 도전 과제 8단계 리팩토링(refactoring): 일정 목록을 조회할 때는 PlanResponseDto 대신 PlanReadResponseDto를 활용하도록 수정하기
🥈 도전 과제 7단계: 댓글 CRUD ▶ 필수 과제 2단계부터 논리 삭제 반영하기
🥉 도전 과제 8단계: 일정 페이징(Paging) 조회 ▶ 필수 과제 1단계부터 주석 보충 및 수정하기 (1순위 할 일과 병행 예정)
4️⃣ 리드미(README) 작성하기: 도전 과제 7-8단계
5️⃣ 리드미(README) 작성하기: 도전 과제 5-6단계
6️⃣ 리드미(README) 작성하기: 필수 과제 3-4단계
7️⃣ 트러블슈팅(troubleshooting) 작성하기