[SPRING] Spring Boot - Hibernate 커스텀 제약이 서비스를 삽입하지 않는다.
SPRINGSpring Boot - Hibernate 커스텀 제약이 서비스를 삽입하지 않는다.
나는 다른 세부 사항을 무시하고 그것을 짧게하려고 노력할 것이다 :
@Entity
public class User
@UniqueEmail
@Column(unique = true)
private String email;
}
@Component
public class UniqueEmailValidatior implements ConstraintValidator<UniqueEmail,String>, InitializingBean {
@Autowired private UserService userService;
@Override
public void initialize(UniqueEmail constraintAnnotation) {
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if(userService == null) throw new IllegalStateException();
if(value == null) return false;
return !userService.isEmailExisted(value);
}
}
이 작업은 Spring에서 유효성 검사 (Spring MVC @Valid 또는 @Autowire를 사용하여 유효성 검사기를 삽입 할 때)가 작동 할 때 모든 것이 정상적으로 작동합니다. 그러나 Spring Data JPA를 사용하여 엔티티를 저장하자마자 :
User save = userRepository.save(newUser);
Hibernate는 UserService 빈을 삽입하지 않고 새로운 UniqueEmailValidatior를 인스턴스화하려고 시도 할 것이다. 그렇다면 어떻게하면 Hibernate가 새로운 UniqueEmailValidatior 컴포넌트를 사용하도록 만들 수 있습니까? spring.jpa.properties.javax.persistence.validation.mode = none을 사용하여 최대 절전 모드 유효성 검사를 비활성화 할 수 있지만 다른 방법이 있기를 바랍니다.
업데이트 : 내 UserService는 다음과 같습니다.
@Autowired private Validator validator;
@Transactional
public SimpleUserDTO newUser(UserRegisterDTO user) {
validator.validate(user);
System.out.println("This passes");
User newUser = new User(user.getUsername(),
passwordEncoder.encode(user.getPassword()),user.getEmail(),
"USER",
user.getAvatar());
User save = userRepository.save(newUser);
System.out.println("This won't pass");
return ....
}
해결법
-
==============================
1.스프링 부트가 기존의 유효성 검사기를 EntityManager에 연결하는 것으로 예상 할 수 있습니다.
스프링 부트가 기존의 유효성 검사기를 EntityManager에 연결하는 것으로 예상 할 수 있습니다.
HibernatePropertiesCustomizer를 사용하고 기존 EntityManagerFactoryBuilder에 속성을 추가하고 유효성 검사기를 등록 할 수 있습니다.
참고 : 여기서는 스프링 부트 2.0을 사용하고 있다고 가정합니다.
@Component public class ValidatorAddingCustomizer implements HibernatePropertiesCustomizer { private final ObjectProvider<javax.validation.Validator> provider; public ValidatorAddingCustomizer(ObjectProvider<javax.validation.Validator> provider) { this.provider=provider; } public void customize(Map<String, Object> hibernateProperties) { Validator validator = provider.getIfUnique(); if (validator != null) { hibernateProperties.put("javax.persistence.validation.factory", validator); } } }
이런 식으로 기존 유효성 검사기를 최대 절전 모드로 연결하고 자동 배선을 사용합니다.
참고 : 유효성 검사기에서 @Component를 사용할 필요가 없습니다. 자동 배선은 유효성 검사기 인스턴스를 반환하기 전에 유효성 검사기 팩토리에 빌드됩니다.
-
==============================
2.Spring Bean을 ConstraintValidator에 삽입하려면 ValidatorFactory 초기화시 전달되어야하는 특정 ConstraintValidatorFactory가 필요하다.
Spring Bean을 ConstraintValidator에 삽입하려면 ValidatorFactory 초기화시 전달되어야하는 특정 ConstraintValidatorFactory가 필요하다.
의 라인을 따라 뭔가 :
ValidatorFactory validatorFactory = Validation.byDefaultProvider() .configure() .constraintValidatorFactory( new MySpringAwareConstraintValidatorFactory( mySpringContext ) ) .build();
MySpringAwareConstraintValidatorFactory는 ConstraintValidator 내에 빈을 삽입하는 ConstraintValidatorFactory입니다.
나는 스프링 데이터에 의해 사용되는 ValidatorFactory가 그들을 생성 할 때 밸리데이터를 삽입하지 않는다고 생각하는데, 이는 불행한 일이다.
나는 당신이 그것을 무시할 수 있어야한다고 생각합니다. 또는, Spring Boot / Spring Data에 대한 이슈를 열어 두 번째로 ConstraintValidators를 제대로 주입 할 수있게해야합니다.
-
==============================
3.대답은 여기에 게시하는 데 아주 큽니다. S.O에서이 기사를 확인하십시오. 이것은 당신이 시작하는 데 도움이됩니다.
대답은 여기에 게시하는 데 아주 큽니다. S.O에서이 기사를 확인하십시오. 이것은 당신이 시작하는 데 도움이됩니다.
Autowired spring 서비스로 맞춤형 검사기 테스트
문제는 최대 절전 모드로 스프링 정의를 알 수 없습니다. 그러나 엔티티가 모든 유형의 javax.validation 유형을 인식하도록 만들 수 있습니다. 희망이 도움이됩니다.
from https://stackoverflow.com/questions/50212117/spring-boot-hibernate-custom-constraint-doesnt-inject-service by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 스프링 부트 액추에이터 엔드 포인트의 JSON 출력을 멋지게 출력 (0) | 2019.04.02 |
---|---|
[SPRING] 봄의 PropertyPlaceHolder (0) | 2019.04.02 |
[SPRING] spring-boot-starter-tomcat 대 spring-boot-starter-web (0) | 2019.04.02 |
[SPRING] Spring MVC Thymeleaf 바인딩 체크 박스가있는 목록 (0) | 2019.04.02 |
[SPRING] Hibernate (4.1.2) 및 Spring (3.1.2) - ManyToMany 관계는 JoinTable에 레코드를 저장하지 않습니다. (0) | 2019.04.02 |