Java 将Hibernate验证程序配置为不使用hashCode()

Java 将Hibernate验证程序配置为不使用hashCode(),java,nullpointerexception,hashcode,hibernate-validator,Java,Nullpointerexception,Hashcode,Hibernate Validator,我有以下对象为我的应用程序的请求建模: @Getter @Setter @ToString public class UserRequest { @NotNull @Size(max = 50) private String name; @Valid private AddressRequest address; } @Getter @Setter @ToString public class AddressRequest { @Siz

我有以下对象为我的应用程序的请求建模:

@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;
    }
}
现在,当客户端在
地址
对象中发送一个包含null
国家
的请求时,会触发验证,但会在my
hashCode()中抛出一个NPE
。这在我这边很容易修复,只需检查null country和其他字段。然而,我宁愿避免这种情况。首先,这发生在很多类上,而不仅仅是这个类。然后,我不喜欢检查空值,特别是当我知道它不应该为空时。它在我的代码中永远不会为空,因为有一个外部工具,我将不得不修改我的代码

我使用Hibernate验证程序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
javax.validation.ValidationException:HV000041:调用TraversableResolver.isRecable()引发异常。
在org.hibernate.validator.internal.engine.ValidatorImpl.isReachable(ValidatorImpl.java:1531)~[hibernate-validator-5.2.2.Final.jar:5.2.2.Final]
在org.hibernate.validator.internal.engine.ValidatorImpl.isValidationRequired(ValidatorImpl.java:1507)~[hibernate-validator-5.2.2.Final.jar:5.2.2.Final]
在org.hibernate.validator.internal.engine.validateImpl.validateMetaConstraint(validateImpl.java:584)~[hibernate-validator-5.2.2.Final.jar:5.2.2.Final]
在org.hibernate.validator.internal.engine.validateImpl.validateConstraint(validateImpl.java:555)~[hibernate-validator-5.2.2.Final.jar:5.2.2.Final]
在org.hibernate.validator.internal.engine.validateImpl.validateConstraintsForDefaultGroup(validateImpl.java:490)~[hibernate-validator-5.2.2.Final.jar:5.2.2.Final]
位于org.hibernate.validator.internal.engine.validateImpl.validateConstraintsForCurrentGroup(validateImpl.java:454)
...
...
位于java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)[na:1.8.066]
在java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)[na:1.8.066]
在org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)[tomcat-embed-core-8.0.28.jar:8.0.28]
在java.lang.Thread.run(Thread.java:745)[na:1.8.0_66]
原因:java.lang.NullPointerException:null
在com.example.dto.AddressRequest.hashCode(AddressRequest.java:106)~[classes/:na]
在org.hibernate.validator.internal.engine.resolver.CachingTraversableResolverForSingleValidation$TraversableHolder.buildHashCode(CachingTraversableResolverForSingleValidation.java:143)~[hibernate-validator-5.2.2.Final.jar:5.2.2.Final]
位于org.hibernate.validator.internal.engine.resolver.CachingTraversableResolverForSingleValidation$TraversableHolder.(CachingTraversableResolverForSingleValidation.java:104)~[hibernate-validator-5.2.2.Final.jar:5.2.2.Final]
在org.hibernate.validator.internal.engine.resolver.CachingTraversableResolverForSingleValidation$TraversableHolder.(CachingTraversableResolverForSingleValidation.java:86)~[hibernate-validator-5.2.2.Final.jar:5.2.2.Final]
在org.hibernate.validator.internal.engine.resolver.CachingTraversableResolverForSingleValidation.isReachable(CachingTraversableResolverForSingleValidation.java:31)~[hibernate-validator-5.2.2.Final.jar:5.2.2.Final]
在org.hibernate.validator.internal.engine.ValidatorImpl.isReachable(ValidatorImpl.java:1522)~[hibernate-validator-5.2.2.Final.jar:5.2.2.Final]
... 省略101个公共帧

因此,此问题已作为解决方案的一部分得到解决

能否将HV升级到最新的稳定版本,例如5.4.1.Final

它应该是一个即插即用的替代品(请参阅此处的迁移指南:)


如果您在升级过程中遇到任何问题,请在此Ping me。

如果国家/地区是强制性的,并且您得到的值为空,则NPE是正确的反应。否则,您的国家/地区不是强制性的,因此不应该在哈希方法中使用它。您可以共享堆栈跟踪吗?可以方便地查看NPE的触发位置。谢谢@GuillaumeSmet补充说,HibernateValidator 4.2.0有解决办法,我有WebSphere8.5ApplicationServer@nprensen,它解决了您的问题吗?