본문 바로가기

Dot Programming/Spring Clone

[스프링 웹앱 프로젝트 #22] Open Entitymanager (또는 Session) In View 필터

23. Open EntityManager (또는 Session) In View 필터

JPA EntityManager(영속성 컨텍스트)를 요청을 처리하는 전체 프로세스에 바인딩 시켜주는 필터
  > 뷰를 렌더링 할 때까지 영속성 컨텍스트를 유지하기 때문에 필요한 데이터를 렌더링하는 시점에 추가로 읽어올 수 있다. (지연 로딩, Lazy Loading)
  > 엔티티 객체 변경은 반드시 트랜잭션 안에서 할 것
    > 그래야 트랜잭션 종료 직전 또는 필요한 시점에 변경 사항을 DB에 반영

현재버그
  > 컨트롤러에서 데이터를 변경했다. 왜 DB에 반영되지 않았을까?
    > 트랜잭션 범위 밖에서 일어난 일이기 때문에!


해결 방법

  > 데이터 변경은 서비스 계층으로 위임해서 트랜잭션안에서 처리한다.

  > 데이터 조회는 레피저토리 또는 서비스를 사용한다. (조회는 굳이 트랜잭션이 없어도 되긴하지만 뷰 렌더링할 때 Lazy Loading가능)

 

모든 Repository는 기본적으로 트랜잭션이 다 적용이 되어있다. 그래서 repo를 통해서 무언가를 하면 다 트랜잭션 통해서 하는 것이라고 생각하면 된다. 서비스단에서 @Transactional의 별도 표시나 repo의 접근 없이 사용할 경우 데이터를 바꾸더라도 DB에는 적용이 안된다.

 

 

1. Controller단에 있는 아래의 코드를 서비스단으로 이동

// account.completeSignUp();
// AccountService.login(account);        
// AccountService.java로 이동
 public void completeSignUp(Account account) {
        account.completeSignUp();
        login(account);
}

 

 

2. AccountService자체에 @Transactional 선언 (DB조회는 성능상 readOnly = true를 해주는 것이 좋음)

@Transactional
public class AccountService implements UserDetailsService {
...


/**
     * DB에 있는 user정보 조회
     * read only -> 조회 용도이기 때문에 (성능에 유리)
     */
    @Transactional(readOnly = true)
    @Override
    public UserDetails loadUserByUsername(String emailOrNickname) throws UsernameNotFoundException {
        Account account = accountRepository.findByEmail(emailOrNickname);
        if(account == null){
            account = accountRepository.findByNickname(emailOrNickname);
        }

        if(account == null){
            throw new UsernameNotFoundException(emailOrNickname);
        }

        //User Principal 반환
        return new UserAccount(account);
    }

}

 

 


결과

버그해결

 

 


JPA UPDATE 몰라...

 

#17 가입 확인 이메일 재전송 에서 나는 이메일 재전송을 할 때마다 토큰 값과 토큰 생성시간을 재할당했었다.

그런데 이번에 서비스단에 영속성을 유지하면서 해당 값이 변경이 되지 않았다.

 

 

첫 회원가입시 주어진 토큰 값

token = eb1aa6b3-ab04-4c36-a889-a80bb5b37911

 

재전송시 주어진 토큰 값

token= 7bdcace1-0330-49d3-93a8-662de7ac883e

 

엔티티와 컨트롤단에도 @Transactional을 선언해보았지만 디버깅결과 account의 토큰 값은 변경이 되지 않았다

 

로그인할 때는 저장이되는데 수정이 안되는 것을 보면 영속성 컨텍스트 Update부분과 관련이 있는 것 같다.

이슈에 등록하고 저 부분을 공부하고 해결해봐야겠다

 

일단은 토큰 값 재설정 기능은 빼놓았다

(사실상 중요한 기능은 아니긴하다)

 

 

 

 

출처 : 인프런 백기선 개발자님