ConstraintValidator problem z @Autowired

0

Witam, otóż mam następujący problem. Posiadam adnotację LoginExsistConstraint, którą wykorzystuję w walidacji ( sprawdzam czy login nie jest już zajęty)

@Documented
@Retention(RUNTIME)
@Target( FIELD)
@Constraint(validatedBy=LoginExistsConstraintValidator.class)
public @interface LoginExsistsConstraint {
	 String message() default "Login already exists";
	 Class[] groups() default {};
	 Class[] payload() default {};

}

oraz klasę implementującą ConstraintValidator

public class LoginExistsConstraintValidator implements ConstraintValidator<LoginExsistsConstraint, String> {

	@Autowired
	private UserRepository userRepository;

		@Override
	public boolean isValid(String login, ConstraintValidatorContext arg1) {
		
		User findByLogin = userRepository.findUserByLogin(login);
	return (findByLogin !=null)? false:true;
	}

}

Teraz robi się ta ciekawsza część. Jeżeli waliduje za pomocą np. adnotacji @Valid

saveUpdateUser(@Valid @ModelAttribute(value="oldUser") User user, 
			BindingResult result, Model model)

to walidacja przebiega bez problemu. Jeżeli jednak chce przeprowadzić walidację tylko jednego pola (update użytkowanika) to pojawia się problem gdyż nie działa @Autowired i userRepository ma wartość null. Walidację jednego pola prowadzę w następujący sposób.

ConstraintValidatorFactory validator = Validation.buildDefaultValidatorFactory().getConstraintValidatorFactory();
LoginExistsConstraintValidator instance = validator.getInstance(LoginExistsConstraintValidator.class);
boolean valid = instance.isValid(user.getLogin(), null);
			

Przeszukałem już cały stack i wykorzystałem wszystkie triki jakie proponują ( łącznie z wywołaniem w metodzie initialize metody SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this); ) ale dalej jest ten sam problem. Może ktoś z was wie czemu ten @Autowired nie działa gdy przeprowadzam walidację tylko jednego pola lub gdzie w mojej walidacji zrobiłem błąd.

1

Oj, joj, joj magia nie działa.

Btw -ale te porady też nie ?
https://stackoverflow.com/questions/13350537/inject-service-in-constraintvalidator-bean-validator-jsr-303-spring
Chodzi o wyciąganie **SpringConstraintValidatorFactory **

0

Tak, próbowałem. Robiłem to w następujący sposób ale efekt ten sam, userRepository null.

@Configuration
public class BeanConfig {
	@Autowired
	private AutowireCapableBeanFactory autowireCapableBeanFactory;

	@Bean
	public SpringConstraintValidatorFactory springConstraintValidatorFactory(){
	 
		return new SpringConstraintValidatorFactory(autowireCapableBeanFactory);
			
	}
}

Jakieś inne pomysły gdzie jest/robie błąd bo już doszedłem do granic internetu w poszukiwaniach ??

0

Dobra, udało się. Bean SpringConstraintValidatorFactory zostaje a samą walidację robię tak:

final ValidatorFactory factory = Validation.byDefaultProvider().configure()
		.constraintValidatorFactory(springConstraintValidatorFactory).buildValidatorFactory();
		final Validator validator = factory.getValidator();
	final Set<ConstraintViolation<User>> validateProperty = validator.validateProperty(user, "login");

@jarekr000000 dzięki za pomoc.

1

To jest bardzo na około zrobione. Tak naprawdę wystarczyło by gdybyś to jedno pole walidował w dwóch grupach. Default oraz jakiejś innej.

0

Dzięki za wskazówkę @Koziołek. Masz rację, Twój sposób jest bardziej elegancki.

1 użytkowników online, w tym zalogowanych: 0, gości: 1