Hibernate bean验证问题

时间:2012-09-24 13:41:40

标签: hibernate validation spring-mvc bean-validation hibernate-validator

我正在使用带有hibernate验证器4.2的spring 3.1。我观察到hibernate验证被调用了两次: 一个在控制器级别,当我使用如下方法:

 @RequestMapping(method = RequestMethod.POST)
    public String onSubmit(@Valid User user, BindingResult result) {....}

第二次将实体作为其中一部分持续存在:

org.hibernate.cfg.beanvalidation.BeanValidationEventListener.validate(..)
org.hibernate.cfg.beanvalidation.BeanValidationEventListener.onPreUpdate(..)
org.hibernate.action.EntityUpdateAction.preUpdate(..)

我认为在控制器级别有效并显示包含错误消息的错误页面更有意义。无论如何,在流程中进行两次相同的验证并不好。 我在hibernate doc中发现可以通过在休眠配置中将hibernate.validator.autoregister_listeners设置为false来关闭它,但不建议这样做。

那么推荐的验证方法是什么?另外在我的特殊情况下,第二次验证会导致问题,因为我有一个字段'confirmPassword',当用户提交表单时需要进行验证,但在表中不需要,所以每当我需要保存,更新用户时,我必须设置confirmPassword字段不必要地使验证通过。

2 个答案:

答案 0 :(得分:1)

即使出现,验证也不是一件容易的事。

前端验证适用于填写表单的用户,可以从视图更改为另一个视图(例如,不同的消息)。视图中必填字段的消息应为“该字段是必填字段!”,在后端实体持久化时:“字段不能为空”。

后端验证应始终在保存类时发生,考虑到事实上可以保存持久实体而不从视图传递(例如,从Web服务接收数据的批处理或从排队ora另一个来源..)。

如果在实体级别放置验证注释,则在该类上强制执行一个独立于该类已在视图中使用的事实的合同。

ConfirmPassword是一个视图字段,所以我认为不应该作为实体中的字段出现(例如,我用JSF开发了一个类似的情况,我在与该视图相关的ManagedBean中放置confirmPassword而不是在实体中,实体仅包含密码字段。)

总之,因此我认为两次进行“相同”验证是正确的。

答案 1 :(得分:0)

一切都取决于用例,并在一定程度上取决于个人品味。 @ obe6建议两个单独的bean,在某些情况下可能有用,但在其他情况下则不然。关于 confirmPassword 字段,您始终可以在实体中将其标记为 @Transient ,以便不会持久保存该值。

我个人可能会通过@Valid禁用Spring验证,因为它不是标准的。另一方面,对JPA生命周期事件的Bean验证是。我想这是另一种品味问题。但两者似乎都没有必要。