Ложное срабатывание PastOrPresent валидатора

Добрый день.

image

У сущности есть поле , хранящее дату.
В качестве Java типа я пробовал Date и LocalDate.

Время от времени наблюдаю сбой валидатора на форме.
Он то дает вводить текущую дату, то не дает. (на скриншоте поле подсвечено красным - ругается, что дата не может быть больше текущей)
image

Из особенностей - приложение запущенно на Ubuntu
image
При подключении вижу корректную дату.

Есть ли предположение с чем может быть связано?
Что стоит попробовать?

PS.
На Windows машине разработчика проблем не наблюдается.
Классика жанра - “У меня все работает” :slight_smile:

Добрый день

Cпасибо за ваш вопрос.

Проблема

Это связано с тем, как работают syscall convention на Windows и Linux(Unix). Например, выражение

var localDateTimeNow = LocalDateTime.now();
var localDateTimeNowTwo = LocalDateTime.now();
assert localDateTimeNow != localDateTimeNowTwo
  • В случае Windows мы получим отрицательный ответ
  • В случае Unix - положительный

Потому, когда пишутся тесты для проверки времени всегда фиксируют delta времени, которое должно снять эффект “не real-time” эффекта ОС.

Получается у вас и другого разработчика на Windows падает валидация на уровне Present

Решение:

  • Как вариант вы можете переопределить BeanValidator внутри конекста Spring, чтобы решит свою проблема
  • Другой способ - использовать валидацию Past

С уважением, команда Jmix.

Большое спасибо за глубокий анализ проблемы.

Всегда пожалуйста, если нужен еще более детальный ответ, такой же вопрос был на англоязычном форуме

Там я более детально описал как эту проблему.
С уважением, команда Jmix

1 симпатия

Добрый день.
Подскажите, проверяли ли вы работу этих аннотаций, с учетом изложенного в комменте:Cuba github issue

Seems that the problem is present in Cuba and Jmix since commit.

When validators created during context initialisation the ClockProvider provides clock with date fixed on application startup date.
Since Hibernate DefaultClockProvider works well, I propose implementing ClockProvider the same way

Вот скриншоты из дебаггера, воспроизвел на jmix-1.5 для аннотации @PastOrPresent
Текущее системное время - 13-30, сервер запущен в 13-10. Уточнение - контекст валидации создается в момент первой попытки валидации поля
org.hibernate.validator.internal.constraintvalidators.bv.time.AbstractJavaTimeValidator#getReferenceValue всегда возвращает 15-03-2024 13:10:54
Если пытаемся сохранит сущность с полем раньше этого времени, то валидация проходит.
13-00
13-30

Временный фикс
/**
 * Фикс работы аннотаций валидации java.Time.*: {@link  javax.validation.constraints.PastOrPresent} и т.д.
 * см
 * .{@link CoreConfiguration#validator(ValidationClockProvider, ValidationTraversableResolver, MessageInterpolator)}
 */
@Primary
@Bean
public ValidationClockProvider delegatingClockProvider() {
	return new DelegatingClockProvider(DefaultClockProvider.INSTANCE);
}

/**
 * Должен переопределять {@link ValidationClockProvider} а не {@link ClockProvider}, т.к. системные бины внедряют
 * зависимости по классу
 */
private class DelegatingClockProvider extends ValidationClockProvider {

	private final ClockProvider delegate;

	public DelegatingClockProvider(ClockProvider delegate) {
		this.delegate = delegate;
	}

	@Override
	public Clock getClock() {
		return delegate.getClock();
	}
}