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();
}
}
🙋♀️
본 포스트는 공부 목적으로 작성하였습니다.
보시는 도중 잘못된 부분이나 개선할 부분이 있다면 댓글로 알려주시면 수정하도록 하겠습니다.
📑
참고 자료
'Java > Spring with Error' 카테고리의 다른 글
[해결 방법] Failed to determine a suitable driver class (1) | 2024.09.28 |
---|---|
[해결 방법] TooManyActualInvocations (0) | 2024.09.22 |
[해결 방법] Argument(s) are different! (0) | 2024.09.15 |
[해결 방법] NoUniqueBeanDefinitionException (0) | 2024.09.04 |
[해결방법] io.jsonwebtoken.ExpiredJwtException (0) | 2024.08.30 |