230313 TIL #31 지연로딩 문제 / User객체 비교 불가

김춘복·2023년 3월 13일
0

TIL : Today I Learned

목록 보기
31/571

230313 Today I Learned

Spring 3주차. Lv.4 과제를 진행중이다. 기존의 프로젝트에 Spring Security를 적용하는 과제중인데 예상치 못한 곳에서 에러가 떠서 막혔다. 기존에는 없었던 에러인데 Security 적용을 하니 에러가 발생했다. 이에 대해 정리해보겠다.


지연로딩 문제

참고사이트

  • 문제점 : 글, 댓글 작성시 failed to lazily initialize a collection of role: com.sparta.blogpostspring.entity.User.commentList, could not initialize proxy - no Session 에러가 뜬다.

  • 시도 : @OneToMany로 설정된 Entity의 컬럼들을 지연로딩에서 Fetch Type EAGER로 바꾸니 해결 되었다. 하지만 이 방법은 근본적인 해결방법이 아니고, 성능을 위해 LAZY가 더 합리적이니, 다른 방법으로 고치는 것을 생각해보자.

  • 해결 : 테스트해보니 연관관계의 주인에서 발생할 수 있는 문제를 잡기위해 양쪽으로 값을 넣어주려던 것이 @Transactional때문에 lazy상태에서 실행되어 발생한 문제였다.

    public Post(PostRequestDto postRequestDto, User user) {
        this.title = postRequestDto.getTitle();
        this.content = postRequestDto.getContent();
        this.user = user;
        user.getPostList().add(this); // 여기가 문제
    }

어차피 Post는 연관관계의 주인이니 양쪽에 넣을 필요까지는 없다. 그래서 아직 딱히 사용처가 없는 @OneToMany들을 지우던가, 아니면 문제가 생긴 양쪽에 값을 넣는 코드를 지우면 해결된다.

  • 알게된 것 : 연관관계의 주인 문제를 해결하기위해 양쪽에다 값을 넣으려 하면, fetchtype.LAZY일때는 오류가 생길 수 있다.
    위의 방법 말고 Lazy로 두고 수정하기 위해서는 여기를 참고하자

동일한 유저로 인식 불가 문제

  • 문제점 : 글 작성유저와 JWT인증유저가 일치함에도 불구하고 일치 여부를 확인하지 못하는 문제. 글, 댓글 수정시 계속 발생 기존에 Spring Security를 적용하지 않았을 때는 아래의 코드를 써도 문제가 없었다.
if (!user.equals(post.getUser())) {
    throw new IllegalArgumentException("작성자만 수정할 수 있습니다.");
}

하지만 Security Filter를 통해 불러온 User가 제대로 인식되지 않아 일치 여부를 제대로 판별하지 못하고 있다. 막상 System.out으로 찍어보면 둘이 같게 나오는데 왜 equals로 비교하면 다르게 나오는지 아직 모르겠다.

  • 시도 : !.equals를 !=로 바꿔서 시도해봤으나 실패.
    일단은 찍어보면 둘이 같게 나오니 객체끼리 직접 비교가 아니라 객체의 id를 뽑아서 비교하게 해봤다.

  • 해결 :

if (!user.getId().equals(post.getUser().getId())) {
    throw new IllegalArgumentException("작성자만 수정할 수 있습니다.");
}

이렇게 하니 정상적으로 작동 되었다.

  • 알게된 점 : 객체끼리 직접 비교보다 객체의 PK(id)만 추출해서 비교하면 위의 문제는 해결할 수 있다.

그런데 Spring Security를 적용하기 전엔 User객체끼리 비교해도 비교가 잘 되었는데, Security적용 후 UserDetails에서 .getUser()로 User를 Service에 넣어주는 방식으로 하니 갑자기 비교가 안되었다. 같은 객체인데 왜그러지? 이 부분은 좀 더 공부해봐야겠다.

두 문제의 진짜원인

TIL #33에 정리해두었다.

profile
Backend Dev / Data Engineer

0개의 댓글