본문으로 바로가기
반응형

개요

현재 Spring Data Redis를 통해 레디스를 다루고 있다. 먼저 아래의 코드부터 살펴보자.

@Getter
@RedisHash(value = "article")
public class RedisArticle {

    @Id
    @Indexed
    private Long id;
    private String title;
    private String description;
    private String nickname;
    private Long commentCount;
    private List<RedisArticleComment> comments = new ArrayList<>();
    private LocalDateTime createTime;
    private LocalDateTime updateTime;

    @Builder
    public RedisArticle(Long id, String title, String description, String nickname,
        List<RedisArticleComment> comments,
        Long commentCount, LocalDateTime createTime, LocalDateTime updateTime) {
        this.id = id;
        this.title = title;
        this.description = description;
        this.nickname = nickname;
        this.commentCount = commentCount;
        this.comments = comments;
        this.createTime = createTime;
        this.updateTime = updateTime;
    }
}

레디스를 위한 엔티티인데 comments를 보면 new ArrayList<>()를 통해 리스트 형태로 초기화를 진행해줬다. 하지만 save() 메소드를 통해 값을 저장할 때 comments값이 없다면 레디스에 저장되는 해시값 내부에 아무런 값이 들어가지 않게 된다. 따라서 findBy~() 메소드를 통해 RedisArticle을 불러온 후 .getComments()를 통해 comments값을 가져오면 리스트로 초기화되어있는게 아닌 null이 반환되게 된다.

문제 상황

List<ArticleCommentDto> comments = article.getComments().stream()
    .map(comment -> ArticleCommentDto.builder()
        .id(comment.getId())
        .body(comment.getBody())
        .nickname(comment.getNickname())
        .articleId(comment.getArticleId())
        .createTime(comment.getCreateTime())
        .updateTime(comment.getUpdateTime())
        .build()
    ).collect(Collectors.toList());

문제가 발생한 상황은 위와 같다. 개요에서 설명한 것 처럼 getComments() 가 리스트 형태라고 생각하여 스트림을 돌렸는데 null이 들어있기 때문에 오류가 발생했다. 

해결 방법

List<ArticleCommentDto> comments = Optional.ofNullable(article.getComments())
    .orElseGet(Collections::emptyList)
    .stream()
    .map(comment -> ArticleCommentDto.builder()
        .id(comment.getId())
        .body(comment.getBody())
        .nickname(comment.getNickname())
        .articleId(comment.getArticleId())
        .createTime(comment.getCreateTime())
        .updateTime(comment.getUpdateTime())
        .build()
    ).collect(Collectors.toList());

해결 방법은 간단하다. 위처럼 Optional.ofNullable()을 통해 대상을 감싸주고 orElseGet()을 통해 만약 null이라면 Collections의 emptyList 즉, 빈 리스트를 넣어주도록 하면 된다. 따라서 위 코드는 null이 아니라면 하위 stream을 실행하게되고 null이라면 단순히 빈 리스트로 만들어지게 된다.

반응형