Я работаю в проекте Java (1.8 и 11) последние несколько месяцев. Мы пытаемся закодировать каждую валидацию, которую мы имеем в наших моделях, в качестве пользовательской валидации javax, которая, на мой взгляд, является «лучшим» методом, который я нашел на данный момент (как всегда, открытым для новых предложений) ... Проблема, однако, заключается в том,когда этому валидатору нужно извлечь данные из базы данных и нескольких валидаторов для одной и той же модели / объекта.
Entity
@DuplicatedUsername
@Getter
@Setter
public class User {
private UUID id;
private String username;
public User(username) {
this.username = username;
}
}
Validator
public class DuplicatedUsernameValidator implements ConstraintValidator<DuplicatedUsername, User> {
@Autowired
private UserRepository userRepository;
@Override
public boolean isValid(User user, ConstraintValidatorContext context) {
if (user.getId() != null) {
return checkForDuplicatedUsername(user.getUsername(), user.getId());
} else {
return checkForDuplicatedUsername(user.getUsername());
}
}
private boolean checkForDuplicatedUsername(String username) {
List<User> users = userRepository.findByUsername(username);
return users.isEmpty();
}
private boolean checkForDuplicatedUsername(String username, UUID id) {
List<User> users = userRepository.findByUsernameAndIdNot(username, id);
return users.isEmpty();
}
}
Тестовый файл
private static Validator validator;
@BeforeClass
public static void setUpValidator() {
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
validator = factory.getValidator();
}
@MockBean
private UserRepository repository;
public void givenDuplicatedSettings_whenValidate_thenReturnInvalid() {
String username = "duplicated";
User user = new User(username);
when(repository.findByUsername(username))
.thenReturn(new User(username));
// What I have
Set<ConstraintViolation<User>> constraintViolations = validator.validate(user);
assertEquals(1, constraintViolations.size());
// What I would like to have
// validator here must be DuplicatedUsernameValidator
assertFalse(validator.isValid(user));
}
Основная причина этого заключается в том, что у пользователя могут быть другие валидаторы, и я не хочу проверять их как единое целое.
Это первая проблема ... Втораясвязан с пружинным контекстом (как всегда) ... Приведенный выше код, даже с Set<ConstraintViolation<User>> constraintViolations = validator.validate(user);
, не работает из-за того, что хранилище является нулевым в коде валидатора. Он не вводится правильно, хотя, когда я его запускаю, он работает как положено. Я использовал следующие аннотации @RunWith(SpringRunner.class)
, @DataJpaTest
и следующий код:
@Primary
@Bean
public Validator validator(){
return new LocalValidatorFactoryBean();
}
Ни один из них не работал должным образом. В какой части головоломки я ошибаюсь?
Заранее спасибо!