При использовании @AssertTrue в методах метод вызывается 4 раза во время проверки (Bean Validation)

При использовании проверки bean для проверки состояния объекта метод, аннотированный с помощью @AssertTrue, вызывается 4 раза всякий раз, когда вызывается проверка. Его следует вызывать только один раз за вызов.

версия для версии Hibernate: 5.1.3. Final

Вот пример:

Для следующего класса Мотоцикл:

import javax.validation.constraints.AssertTrue;
class Motorcycle{
    private int fuel;
    private int tireDurability;

    @AssertTrue(message = "motorcycle.not.available.to.use")
    public boolean isAvailable(){
        return fuel > 0 && tireDurability > 0;
    }

    public void toUse(){...}
}

И главное:

import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
public class Main{
    public static void main(String []args){
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        Validator validator = factory.getValidator();

        Set<ConstraintViolation<Motorcycle>> violations = validator.validate(new Motorcycle());

    }
}

Когда вызывается validator.validate(new Motorcycle()), метод isAvailable() вызывается 4 раза.

Может ли кто-нибудь помочь мне в этой ситуации? Это ошибка? Как мне обойти это?

Ответ 1

Вам следует попробовать использовать Hibernate Validator 6.0.2.Final(в настоящее время это последняя доступная версия). Следующий тест проходит с этой (последней) версией валидатора:

@Test
public void testMotorcycle() throws Exception {
    AtomicInteger count = new AtomicInteger( 0 );

    Motorcycle motorcycle = new Motorcycle( count );
    validator.validate( motorcycle );
    assertEquals( motorcycle.count.get(), 1 );
}

class Motorcycle {
    final AtomicInteger count;
    private int fuel;
    private int tireDurability;

    Motorcycle(AtomicInteger count) {
        this.count = count;
    }

    @AssertTrue(message = "motorcycle.not.available.to.use")
    public boolean isAvailable() {
        count.incrementAndGet();
        return fuel > 0 && tireDurability > 0;
    }

}

Я попытался запустить его с 5.1, а также - и он также проходит там. Как вы определили, что метод называется 4 раза?