• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    해결됨

특정엔티티의 영속성 컨텍스트 유지

21.01.14 19:53 작성 조회수 394

0

안녕하세요 영한님

제가 개발을 하다가 막히는부분이 있어 질문드립니다.

현재 세션이 아닌 토큰 발급 방식으로 개발을 했는데 문제는 토큰 유효성 검사를 하는 필터에서 db에 해당 토큰의 시그니쳐로 유저 엔티티를 조회한다는겁니다..

여기서 문제가 서비스레이어에서는 또 유저 엔티티를 조회하다보니 중복된 쿼리가 날라갑니다..

하이버네이트 2차 캐시를 적용해봤지만 서버가 다중화 되어있다보니 문제가 생길것 같습니다..

필터에서 조회한 유저 엔티티를 서비스레이어 트랜잭션 까지만 유지하고 싶은데 혹시 방법이 있을까요? 

OSIV 외에 다른 방법이 있을지 해서 문의드립니다.

답변 4

·

답변을 작성해보세요.

3

안녕하세요. 진호님

ThreadLocal을 만들어서 거기에 넣어두는 것은 괜찮습니다.

그런데 ArgumentResolver로 검색해보시면 컨트롤러에서 해당 Dto를 바로 파라미터로 받을 수 있는 방법을 찾을 수 있을거에요.

두번째 질문은 사실 처음과 같은 질문인데요.

아마 사용자 정보를 수정하고 싶어서 그러신 것 같아요. 사용자를 한번 더 조회하더라도, 트랜잭션이 있는 곳에서 처음부터 다시 조회하는 것이 더 나은 선택입니다.

필터에서 조회한 유저를 서비스에서 수정하려면, 결국에 트랜잭션을 필터부터 시작해야 하기 때문에 좋은 방법이 아니고, 유지보수도 어렵습니다.

두번 조회라는 것이 성능 때문에 고민이 있을 수도 있지만, 사실 실제 애플리케이션을 생각해보면, 사용자 정보를 수정하는 경우는 거의 없습니다. 그렇기 때문에 이런 경우는 두번을 조회하더라도 전체 애플리케이션에 미치는 영향은 바다의 모래알 같은 것입니다. 이것을 어떻게든 해결하기 위해서 복잡한 방법을 사용하면 유지보수가 매우 어려운 애플리케이션이 됩니다.

사실 뭔가 엄청 고민을 한다는 것은 반대로 생각해보면, 그 고민이 근본적으로 잘못된 수일 가능성이 높습니다.

도움이 되셨길 바래요^^

3

안녕하세요. 이진호님

지금 고민이 토큰을 조회할 때 회원정보를 이미 조회했는데, 서비스레이어에서 또 유저를 조회하는 것이 고민이시군요.

먼저 필터에서 조회한 유저 엔티티를 서비스레이어 트랜잭션 까지만 유지하는 하는 것은 좋은 방법이 아니라 생각합니다.

이런 문제는 사실 단순하게 풀어야 합니다.

필터 같은 계층에서는 엔티티를 조회하지 말고, 회원과 인증에 필요한 최소한의 정보만 담은 DTO로 조회하는 것이 좋습니다. 그리고 이 DTO를 request.setAttribute() 같은 곳에 저장해두고, 컨트롤러 같은 곳에서 꺼내서 필요한 서비스에 넘기면 됩니다. 그러면 두번 조회하는 문제가 해결되겠지요.

DTO 대신에 엔티티를 이런 곳에 담아서 넘기면 영속 상태나, 준영속 상태등을 고민해야 하기 때문에 문제 해결이 복잡해지고 신경쓸 일도 많아집니다. 반면에 DTO는 이런 곳에 마음껏 넘기셔도 됩니다.

감사합니다.

2

이진호님의 프로필

이진호

질문자

2021.01.15

넵 많은 도움이 되었습니다. 상세하고 친절한 답변 정말 감사합니다!!!

0

이진호님의 프로필

이진호

질문자

2021.01.15

답변 감사합니다. 

말씀해주신대로 Dto로 캐시해서 사용해보려고 합니다.

그 부분에서 request 대신 ThreadLocal 객체를 하나 만들고 거기에 캐시해두려고 하는데 괜찮을까요?

컨트롤러에서 request를 아예 받지 않는 상황이어서 그렇습니다.

아.. 또 하나 해결이 안되는게..

가장 앞단 토큰 검사에서 유저의 엔티티를 가져오고 그 이후의 서비스 레이어에서 유저의 레이지 로딩으로 가져오고 싶은데...

방법이 없을까요ㅠㅠㅠ

또 업데이트하려면 엔티티를 또 조회해야하기도 하고요..

제가 jpa 기본을 듣지 못해서 해결방법이 떠오르질 않습니다..