본문 바로가기
Java/Spring with Error

[해결 방법] "this.bCryptPasswordEncoder" is null

by HJ0216 2024. 11. 12.

java.lang.NullPointerException: Cannot invoke "org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder.encode(java.lang.CharSequence)" because "this.bCryptPasswordEncoder" is null

Environment
Language: Java 17
Framework: SpringBoot 3.1.0, Spring Security 6.1.0
DB: MySQL, Redis

 

오류

java.lang.NullPointerException: 
Cannot invoke "org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder.encode(java.lang.CharSequence)" 
because "this.bCryptPasswordEncoder" is null

 

 

원인

@Builder
@AllArgsConstructor
@Getter
public class SignUpRequestDTO {

  private final BCryptPasswordEncoder bCryptPasswordEncoder;

  public User toEntity() {
    return User.builder()
               .status(userType.substring(0, 1).toUpperCase())
               .userType(UserType.valueOf(userType.toUpperCase()))
               .email(email)
               .phone(phone)
               .nickname(nickname)
               .password(bCryptPasswordEncoder.encode(password))
               .role(getRole())
               .build();
  }
}

bCryptPasswordEncoder 인스턴스가 주입되지 않음

 

SignUpRequestDTO가 빈으로 등록되지 않았으므로 Spring에서는 @Bean으로 등록된 BCryptPasswordEncoder를 자동으로 주입할 수 없음

 

해결

1. SignUpRequestDTO을 Bean으로 등록

🚨 DTO는 일반적으로 데이터 전송 객체로 사용되며, 빈으로 관리되는 경우가 거의 없음

@Bean
@Builder
@AllArgsConstructor
@Getter
public class SignUpRequestDTO {

  private final BCryptPasswordEncoder bCryptPasswordEncoder;

  public User toEntity() {
    return User.builder()
               .status(userType.substring(0, 1).toUpperCase())
               .userType(UserType.valueOf(userType.toUpperCase()))
               .email(email)
               .phone(phone)
               .nickname(nickname)
               .password(bCryptPasswordEncoder.encode(password))
               .role(getRole())
               .build();
  }
}

 

2. Service 클래스에서 BCryptPasswordEncoder를 주입

UserService.java
Bean으로 등록된 UserSerivce에서 BCryptPasswordEncoder를 주입받아 SignUpRequestDTO로 전달
@Slf4j
@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class UserService {

  private final BCryptPasswordEncoder bCryptPasswordEncoder;

  @Transactional
  public void create(SignUpRequestDTO signUpRequestDTO) {
    emailDuplicateCheck(signUpRequestDTO.getEmail());
    userRepository.save(signUpRequestDTO.toEntity(bCryptPasswordEncoder));

    log.info("User successfully created for email: {}", signUpRequestDTO.getEmail());
  }
}

 

SignUpRequestDTO.java
@Builder
@AllArgsConstructor
@Getter
public class SignUpRequestDTO {

  public User toEntity(BCryptPasswordEncoder bCryptPasswordEncoder) {
    return User.builder()
               .status(userType.substring(0, 1).toUpperCase())
               .userType(UserType.valueOf(userType.toUpperCase()))
               .email(email)
               .phone(phone)
               .nickname(nickname)
               .password(bCryptPasswordEncoder.encode(password))
               .role(getRole())
               .build();
  }
}

 

 

 

🙋‍♀️

본 포스트는 공부 목적으로 작성하였습니다.
보시는 도중 잘못된 부분이나 개선할 부분이 있다면 댓글로 알려주시면 수정하도록 하겠습니다.

 

📑

참고 자료