겪은 문제

@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에 트랜잭션?

이 문제를 처음에 해결하지 못 하고, 컨트롤러에 트랜잭션을 생성했었다.

그러나 계속 요청을 받고 있는 컨트롤러에 트랜잭션 환경을 만드는 지양해야 한다.

+ Recent posts