겪은 문제
@Service
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;
private final UserMapper userMapper;
public final User signup(UserSignupRequestDto requestDto) {
User user = this.userMapper.toEntity(requestDto);
return this.userRepository.save(user);
}
@Transactional
public void verify(User user) {
user.verify();
}
}
나는 verify 메서드에 트랜잭션을 설정했는데, 아무런 상관 없는 userMapper가 갑자기 null이 되어버렸다...
signup 메서드는 건들지도 않았는데?
왜 뚱딴지 같은 곳에서 문제가 생긴 걸까?
원인
그것은 signup 메서드에 final 키워드가 사용 되었다는 것이다.
@Transactional은 스프링 AOP를 통해 프록시로 작동된다.
프록시 객체는 트랜잭션이 적용 되어있는 클래스를 상속하여 구현이 되는데,
final 키워드 때문에 signup 메서드의 오버라이딩이 되지 않은 것이다.
해결
@Service
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;
private final UserMapper userMapper;
public User signup(UserSignupRequestDto requestDto) {
User user = this.userMapper.toEntity(requestDto);
return this.userRepository.save(user);
}
@Transactional
public void verify(User user) {
user.verify();
}
}
final 키워드를 제거 하면 해결된다.
+ Controller에 트랜잭션?
이 문제를 처음에 해결하지 못 하고, 컨트롤러에 트랜잭션을 생성했었다.
그러나 계속 요청을 받고 있는 컨트롤러에 트랜잭션 환경을 만드는 지양해야 한다.
'Spring' 카테고리의 다른 글
[Spring] JUnit 5 단위 테스트 (0) | 2024.06.11 |
---|---|
[Spring] Naver, Google 로그인 (OAuth2) (0) | 2024.06.10 |
[Spring] Naver 로그인 (Oauth2 X) (1) | 2024.06.08 |
[Spring] JPA Hibernate 칼럼 파싱 문제 (0) | 2024.06.05 |
[Spring] 이메일 인증하기 feat. google SMTP (0) | 2024.06.04 |