2023년 1월 1일
08:00 AM
Buffering ...

최근 글 👑

Redis에 저장된 객체의 ID가 null로 반환되는 문제

2024. 9. 26. 01:19ㆍ트러블슈팅

평화롭게 공부를 하며 프로젝트 코드를 작성하고 데이터를 redis로 저장하고 포스트맨으로 테스트를 하다가 발견한 null....너 왜 여기있니..?

너 거기 있으면 큰일나.. 어서 나와..


저게 뭐지? id 값을 자동으로 설정해주도록 했었는데,,? 내가 삭제했나?

위에 코드를 보면서 객체는 저장되어있는데 id가 null이면 저장이 안된건가..?? 한참 생각했다

 

문제의 원인은 이러했다

  • cart 저장하는 로직에 자동으로 id 값을 할당하는 로직이 빠져있었다..!
  • 기본적으로 cart 객체는 id 값을 가지고 있어야 했으나, Redis에서 새로 생성된 Cart 객체는 id값이 null로 남아있었다..!
  • 객체 생성 후 id가 자동으로 값이 증가하거나 하는 로직이 없기 때문에 다시 cart 객체를 redisd에 저장해도 null 값으로 저장되었다...

문제의 원인을 알았으니 빠르게 다시 코드를 수정해보자.!!

 

수정하는 과정에서 AtomicLong을 사용하여 id값을 자동으로 증가하도록 작성하였습니다!

AtomicLong을 사용한 이유 --> ?

AtomicLong을 사용한 이유는 객체가 생성될 때마다 고유한 숫자형 ID를 자동으로 증가시키기 위해서 사용했습니다!

AtomicLong은 스레드 안전한 클래스로, 여러 스레드에서 동시에 접근해도 값을 안전하게 증가시킬 수 있습니다. 즉, 여러 곳에서 동시에 Cart 객체를 생성해도 고유한 id 값을 보장할 수 있습니다.
@RedisHash("cart")  // Redis에서 관리됨
@Getter
@NoArgsConstructor
public class Cart {
    private static final AtomicLong idGenerator = new AtomicLong(1);  // 자동 증가하는 ID 생성기

    private Long id;  // Redis에서 관리되는 ID
    private Long userId;  // User 대신 userId를 저장
    private List<CartItem> cartItems = new ArrayList<>();

    public Cart(Long userId) {
        this.userId = userId;
        this.id = idGenerator.getAndIncrement(); //자동 증가 Id
    }

 

 

필자는 마지막 부분인 this.id = idGenerator.IncrementAndGet()을 사용했었다...IncrementAndGet()은 값을 먼저 증가시킨 후 그 값을 반환하기 때문에, 예상과 달리 id가 바로 설정되지 않는 문제가 있다.. 이 문제를 겪고 getAndIncrement()로 변경을 하였다..!

 

변경을 해서 다시 시작해보니 결과는....

201 Created!!!!!!!!!!!!!


다행히 문제는 해결되었다..

 

별거 아닌 에러였지만 등에 식은땀이,,,,

 

이번 에러를 통해서 차분하게 디버깅을 해보면서 어디에서 문제가 발생하는지 확인할 수 있었고 그 덕분에 에러를 빠르게 해결할 수 있었다.그리고 getAndIncrement()와 incrementAndGet()의 차이점에 대해서 알게되어 굉장히 유익한 시간이였다고 할 수 있다..!