2023.09.04.월.TIL

heeh·2023년 9월 11일

TIL

목록 보기
78/82
post-thumbnail

2023.09.04.월.TIL

  • 할 것
    • 회원 탈퇴

체크

  • 환경변수 추가 REGION
  • Run 안되면 서울 API 테이블 드랍!

회원 탈퇴

  • 참고
  • 회원 탈퇴를 처리하고 탈퇴한 회원 정보를 Redis에 저장하고 30일 후에 삭제하는 방법은 Redis의 TTL(Time To Live)을 활용하여 구현할 수 있음
    • TTL : 데이터가 Redis에서 유지되는 시간을 설정하는 기능
  • public class Withdrawal
    • Redis의 redisTemplate을 사용하여 userId에 대한 TTL을 설정하고 문자열 "withdrawal"을 값으로 저장하고 있습니다. 이것은 특정 키에 대한 TTL을 설정하는 데 사용되는 일반적인 방법 중 하나입니다. 이 코드는 Redis에서 사용자 ID(userId)를 키로 사용하고, 해당 키의 값으로 "withdrawal" 문자열을 저장하며, 그 키를 30일 동안 유지합니다. 이 방법은 잘 작동할 것으로 보입니다.
      package com.sparta.seoulmate.entity.redishash;
      
      import lombok.AllArgsConstructor;
      import lombok.Getter;
      import org.springframework.data.redis.core.RedisHash;
      import org.springframework.data.redis.core.RedisTemplate;
      
      import java.util.concurrent.TimeUnit;
      
      @RedisHash(value = "withdrawal")
      @Getter
      @AllArgsConstructor
      public class Withdrawal {
      
          private static final String WITHDRAWAL_KEY_PREFIX = "withdrawal:";
      
          private RedisTemplate<String, String> redisTemplate;
      
          public void saveWithdrawalInfo(String userId) {
              String key = WITHDRAWAL_KEY_PREFIX + userId;
              // 여기에서 회원 정보를 Redis에 저장
              redisTemplate.opsForValue().set(key, "withdrawal");
              // TTL 30일로 설정
              redisTemplate.expire(key, 30, TimeUnit.DAYS);
          }
      }
    • Redis의 @TimeToLive 어노테이션을 사용하여 TTL을 설정하려는 것 같은데, 이 방법은 Spring Data Redis의 @TimeToLive 기능을 사용하는 방법입니다. 이 방법은 Redis의 EXPIRE 명령어를 내부적으로 사용하여 TTL을 설정합니다. 그러나 주의할 점은 @TimeToLive 어노테이션은 엔티티 클래스에 적용되어야 하며, 일반적으로 JPA Entity나 Spring Data Redis의 Repository에 사용됩니다. 만약 이 방법을 사용하려면 Withdrawal 클래스를 Redis Entity로 구성해야 합니다.
      package com.sparta.seoulmate.entity.redishash;
      
      import lombok.AllArgsConstructor;
      import lombok.Getter;
      import org.springframework.data.redis.core.RedisHash;
      import org.springframework.data.redis.core.TimeToLive;
      
      @RedisHash(value = "withdrawal")
      @Getter
      @AllArgsConstructor
      public class Withdrawal {
      
          private static final String WITHDRAWAL_KEY_PREFIX = "withdrawal:";
      
          private String userId;
      
          @TimeToLive
          private Long expiration; // TTL 설정
      
          public Withdrawal(String userId) {
              this.userId = userId;
              this.expiration = 30L * 24 * 60 * 60; // 30일 동안 유지
          }
      }
    • 첫 번째 방법은 더 직관적이며 Redis의 일반적인 사용 방법과 가장 일치합니다. 두 번째 방법은 Spring Data Redis의 기능을 사용하여 더 간단한 설정을 제공할 수 있지만, 프로젝트의 요구 사항에 따라 적합하지 않을 수 있습니다.
      • @RedisHash(value = "withdrawal") 어노테이션은 Redis에서 이 클래스가 해시로 저장되어야 함을 나타냅니다.
      • @TimeToLive 어노테이션은 데이터의 TTL(Time To Live)을 설정하는 데 사용됩니다. 이 어노테이션을 사용하면 데이터가 저장될 때 TTL이 설정되며, TTL이 만료되면 데이터가 Redis에서 자동으로 삭제됩니다.
      • expiration 필드는 TTL을 나타내며, 여기서는 30일 동안 유지됩니다.
      • userId 필드는 Redis에 저장할 데이터의 키 역할을 합니다.
  • 기간 설정 할 수 있는 방법 2가지?
    • Redis에서 만료된 데이터를 주기적으로 스캔하고 삭제하는 작업은 Redis 자체에서 TTL(Time To Live) 설정을 활용하여 자동으로 처리
    • 스케줄링을 사용하여 주기적으로 만료된 데이터를 처리, Spring의 @Scheduled 어노테이션을 사용
  • return
    • throw new IllegalArgumentException(" "); 대신
    • return new ResponseEntity<>(" ", HttpStatus.OK); 을 쓸 수 있다
  • 오류
    Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
    2023-09-04T19:52:50.462+09:00 ERROR 6708 --- [           main] o.s.boot.SpringApplication               : Application run failed
    
    org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userController' defined in file
    • Redis에서 사용되는 Withdrawal 엔티티 클래스에 @Id 필드가 누락되어 발생
    • Withdrawal 클래스에 @Id 어노테이션을 추가하여 userId 필드를 엔티티의 주요 키로 지정
      @Id // userId를 엔티티의 주요 키로 지정
          private String userId;
  • 삭제 메서드 or 로직
    • 시간 기한이 다 지나면 삭제 될 수 있게끔 로직을 짜주어야 하는 것이 아닌가?
      • Withdrawal 엔티티에 TTL을 설정하면 해당 데이터는 TTL이 만료되면 Redis에서는 삭제되지만, 이를 트리거하는 코드는 따로 작성할 필요가 없습니다. Redis는 내부적으로 스캔 작업을 수행하여 만료된 데이터를 삭제합니다.
  • User Entity에 private boolean withdrawalRequested;를 추가해 줘서 탈퇴 신청 여부를 users table에서 확인하기
    		@Column
        private boolean withdrawalRequested;
  • NullPointerException 오류
    • 원인
      • this.withdrawalRequested에서 booleanValue() 메서드를 호출할 때 발생
      • withdrawalRequested 프로퍼티가 null인 상태에서 해당 프로퍼티에 접근하려고 시도할 때 발생
    • 해결
      public boolean isWithdrawalRequested() {
          return withdrawalRequested != null && withdrawalRequested;
      }
      • withdrawalRequested가 null이 아니고 true인 경우에만 true를 반환하며, 그 외의 경우에는 false를 반환합니다. 이렇게 하면 withdrawalRequested가 null인 경우에도 NullPointerException이 발생하지 않아야 합니다.
    • 해설
      • withdrawalRequested 필드를 기본적으로 boolean(primitive type)으로 정의
      • 기본적으로 boolean(primitive type)으로 선언된 변수는 초기화되지 않으면 자동으로 기본값인 false가 할당
      • 객체지향 언어에서는 기본적으로 클래스의 멤버 변수들은 초기화되지 않은 상태로 생성
      • withdrawalRequested 필드는 null 상태가 아니라 초기화되지 않았을 때 false로 간주되는데, 이런 경우에 해당 필드를 사용하면 NullPointerException이 발생
      • withdrawalRequestednull인지 체크하고, 그 후에 withdrawalRequested 값이 true인 경우에만 true를 반환하도록 하기
    • 결론
      • withdrawalRequested 필드가 null이거나 false일 때는 항상 false가 반환되므로 NullPointerException 오류를 예방

19시 중간 발표

  • 소프트웨어 아키텍쳐(서비스 아키텍쳐) 추가해야 함
    • 그림..?
  • 프론트 추가 예정
  • 알림 추가 예정
  • 채팅 추가 예정
  • 공공 api 불러들이는 것이 50초에서 7초 정도로 단축!
    → 엔티티를 모아서 한 번에 처리해주는 방식으로 바꿈
    → 자세한 리뷰, 사항은 또 물어보기!
profile
공부하자개발하자으쌰으쌰

0개의 댓글