我正在使用 Hibernate Validation 6.x。我正在验证的对象中有一个字段,其中包含一个列表 List<@NotNull Double> doubles
例如。我面临的问题是,当列表非常大时,性能下降是很大的。为了调查这个问题,我将列表元素的验证实现为列表上的自定义 validator ,@ValidDoubles List<Double> doubles
,使用流迭代元素,并为该 validator 实现了约 65% 的性能提升。
分析应用程序后,我可以看到大部分时间都花在 ListValueExtractor.extractValues
上。 ,可以找到here .我希望有人可以解释为什么这种方法似乎如此昂贵,以及是否有任何已知的解决方法。
一个示例对象:
public class myDataObject {
private List<@NotNull Double> doubles // List which can contain thousands of values
// Getters and Setters
}
更新 经过进一步的分析和调查,我认为这个问题与 Hibernate 在执行级联验证时跟踪哪些 bean 已经过验证有关,特别是使用
System.identityHashCode
这样做时(Here is the code)。查看我的分析器,我可以看到 11.6% 的 CPU 时间用于验证输入 bean。其中,11.3% 的时间用于调用
System.identityHashCode
.有趣的是,尽管它们包含相对简单的验证,但花费时间的是第二个子对象。我想知道我是否错误地配置了 validator 或 bean,因为这似乎很奇怪。我的 validator 配置如下所示:
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="validationPropertyMap">
<util:map>
<entry key="hibernate.validator.fail_fast" value="true"/>
</util:map>
</property>
</bean>
validator 调用:Set<ConstraintViolation<InputObject>> violations = validator.validate(input);
示例对象结构public class InputObject {
@NotNull
String name;
@Valid
List<FirstChild> firstChildren; // on average 10 objects but can be up to very large
// Getters and Setters
}
public class FirstChild {
@SomeCustomValidator // Not important
Integer someValue;
// 3 to 4 further fields with simple validators
@Valid
List<SecondChild> secondChildren; // On average around 40 objects but can be very large
// Getters and Setters
}
public class SecondChild {
@NotBlank
String foo;
@NotBlank
String bar;
// Getters and Setters
}
综上所述:@Valid
中找到的级联验证。 list 上的注释。 System.identityHashCode
因为该方法占用了大部分验证时间。 这是 Hibernate 的优化问题,还是我可以以某种方式配置我的 validator 或输入对象结构以产生更好的性能?
最佳答案
艰难的一个。
所以你看到的问题是我们创建了一个 BeanGroupProcessedUnit
每个列表值,所以当你有很多时,它不能很好地扩展。
将内容移出列表时不会出现问题,因为我们只为整个列表保留一个已处理的单元。
我不完全确定是否有一个简单的解决方案不会破坏其他用例,但我们至少应该检查我们是否可以在您遇到的情况下改善情况。
话虽如此,如果您能花时间在我们的跟踪器 https://hibernate.atlassian.net/projects/HV/issues 上打开一个问题,我将不胜感激。使用基于 https://github.com/hibernate/hibernate-test-case-templates/tree/master/validator 的复制器?这将有助于启动该过程。
关于java - Hibernate Validation 6.0 ListValueExtractor.extractValues 似乎对大型列表的性能很差,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66177098/