Настройте Hibernate Validator, чтобы не использовать hashCode ()

У меня есть следующие объекты, моделирующие запросы к моему приложению:

@Getter
@Setter
@ToString
public class UserRequest {

    @NotNull
    @Size(max = 50)
    private String name;

    @Valid
    private AddressRequest address;

}


@Getter
@Setter
@ToString
public class AddressRequest {

    @Size(max = 50)
    private String street;

    @Size(max = 50)
    private String postcode;

    @NotNull
    private String country;

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        AddressRequest that = (AddressRequest) o;

        if (street != null ? !street.equals(that.street) : that.street != null) {
            return false;
        }
        if (postcode != null ? !postcode.equals(that.postcode) : that.postcode != null) {
            return false;
        }
        if (country != that.country) {
            return false;
        }
        return true;

    }

    @Override
    public int hashCode() {
        int result = street != null ? street.hashCode() : 0;
        result = 31 * result + (postcode != null ? postcode.hashCode() : 0);
        result = 31 * result + country.hashCode();
        return result;
    }
}

Теперь, когда клиент отправляет запрос с нулевым country внутри объекта address, срабатывает проверка, но в моем hashCode() выдается NPE. С моей стороны это очень легко исправить, просто проверив пустую страну, как и в других полях. Однако я бы предпочел этого избежать. Во-первых, это происходит с множеством классов, а не только с этим. Тогда мне не нравится проверять нулевые значения, особенно когда я знаю, что они не должны быть нулевыми. В моем коде он никогда не будет нулевым, мне придется изменить свой код из-за внешнего инструмента.

Я использую Hibernate Validator 5.2. Есть ли способ настроить его, чтобы этого избежать?

Это трассировка стека из NPE:

javax.validation.ValidationException: HV000041: Call to TraversableResolver.isReachable() threw an exception.
    at org.hibernate.validator.internal.engine.ValidatorImpl.isReachable(ValidatorImpl.java:1531) ~[hibernate-validator-5.2.2.Final.jar:5.2.2.Final]
    at org.hibernate.validator.internal.engine.ValidatorImpl.isValidationRequired(ValidatorImpl.java:1507) ~[hibernate-validator-5.2.2.Final.jar:5.2.2.Final]
    at org.hibernate.validator.internal.engine.ValidatorImpl.validateMetaConstraint(ValidatorImpl.java:584) ~[hibernate-validator-5.2.2.Final.jar:5.2.2.Final]
    at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraint(ValidatorImpl.java:555) ~[hibernate-validator-5.2.2.Final.jar:5.2.2.Final]
    at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForDefaultGroup(ValidatorImpl.java:490) ~[hibernate-validator-5.2.2.Final.jar:5.2.2.Final]
    at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForCurrentGroup(ValidatorImpl.java:454) 
    ...
    ...
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_66]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_66]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.0.28.jar:8.0.28]
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_66]
Caused by: java.lang.NullPointerException: null
    at com.example.dto.AddressRequest.hashCode(AddressRequest.java:106) ~[classes/:na]
    at org.hibernate.validator.internal.engine.resolver.CachingTraversableResolverForSingleValidation$TraversableHolder.buildHashCode(CachingTraversableResolverForSingleValidation.java:143) ~[hibernate-validator-5.2.2.Final.jar:5.2.2.Final]
    at org.hibernate.validator.internal.engine.resolver.CachingTraversableResolverForSingleValidation$TraversableHolder.<init>(CachingTraversableResolverForSingleValidation.java:104) ~[hibernate-validator-5.2.2.Final.jar:5.2.2.Final]
    at org.hibernate.validator.internal.engine.resolver.CachingTraversableResolverForSingleValidation$TraversableHolder.<init>(CachingTraversableResolverForSingleValidation.java:86) ~[hibernate-validator-5.2.2.Final.jar:5.2.2.Final]
    at org.hibernate.validator.internal.engine.resolver.CachingTraversableResolverForSingleValidation.isReachable(CachingTraversableResolverForSingleValidation.java:31) ~[hibernate-validator-5.2.2.Final.jar:5.2.2.Final]
    at org.hibernate.validator.internal.engine.ValidatorImpl.isReachable(ValidatorImpl.java:1522) ~[hibernate-validator-5.2.2.Final.jar:5.2.2.Final]
    ... 101 common frames omitted

person garci560    schedule 22.03.2017    source источник
comment
Если страна является обязательной, и вы получаете нулевые значения, правильной реакцией будет NPE. В противном случае ваша страна не является обязательной, и тогда она вообще не должна использоваться в методе хеширования.   -  person Rene M.    schedule 22.03.2017
comment
Не могли бы вы поделиться трассировкой стека? Может быть удобно увидеть, где срабатывает NPE. Спасибо!   -  person Guillaume Smet    schedule 22.03.2017
comment
@GuillaumeSmet Добавлен   -  person garci560    schedule 22.03.2017
comment
Вот обходной путь для HibernateValidator 4.2.0, у меня был сервер приложений Websphere 8.5 stackoverflow.com/a/59514454/3333878   -  person abitcode    schedule 28.12.2019


Ответы (1)


Таким образом, эта проблема была исправлена ​​в рамках https://hibernate.atlassian.net/browse/HV-1013.

Можете ли вы обновить HV до последней стабильной версии, например. 5.4.1.Финал?

Это должна быть прямая замена (см. Руководство по миграции здесь: https://developer.jboss.org/wiki/HibernateValidatorMigrationGuide).

Свяжитесь со мной здесь, если у вас возникнут проблемы с обновлением.

person Guillaume Smet    schedule 22.03.2017
comment
@nprensen, проблема устранилась? - person Guillaume Smet; 24.03.2017