【问题标题】:javax.validation.ConstraintViolationException: validation failed for classes during persist time for groups [javax.validation.groups.Default, ]javax.validation.ConstraintViolationException:在组的持续时间内对类的验证失败[javax.validation.groups.Default,]
【发布时间】:2011-11-24 17:42:58
【问题描述】:

我的实体在 name 字段上有 bean 验证注释 @NotBlank@Size。但是,当我提交 name 字段留空的 JSF 表单时,它不会验证该字段。

这是有问题的字段:

@NotBlank(message = "{name.required}")
@Size(max = 25, message = "{long.value}")
@Column(name = "name", length = 25, nullable = false)
private String name;

在不输入任何数据的情况下提交表单时,我收到以下异常:

Caused by: javax.faces.el.EvaluationException: javax.validation.ConstraintViolationException: validation failed for classes [com.myapp.domain.Department] during persist time for groups [javax.validation.groups.Default, ]
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:102)
    at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
    ... 89 more
Caused by: javax.validation.ConstraintViolationException: validation failed for classes [com.myapp.domain.Department] during persist time for groups [javax.validation.groups.Default, ]
    at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.validate(BeanValidationEventListener.java:132)
    at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.onPreInsert(BeanValidationEventListener.java:71)
    at org.hibernate.action.EntityInsertAction.preInsert(EntityInsertAction.java:177)
    at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:72)
    at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:268)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:260)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:179)
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1206)
    at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:375)
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:137)
    at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:656)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:393)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
    at $Proxy212.addDepartment(Unknown Source)
    at com.myapp.beans.DepartmentBean.addOrUpdateDepartment(DepartmentBean.java:105)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.el.parser.AstValue.invoke(AstValue.java:262)
    at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:278)
    at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)

这是怎么引起的,现在可以解决吗?


更新:这是视图的相关部分:

<h:form>         
    <ice:panelGrid columns="3">
        <h:outputLabel>Department Name:</h:outputLabel>
        <h:inputText id="name" value="#{departmentBean.departmentObj.name}" />
        <h:message for="name" />
    </ice:panelGrid>        
</h:form>
<h:form>
    <ice:panelGroup>
        <h:commandLink value="Add New" action="#{departmentBean.addOrUpdateDepartment}" />
    </ice:panelGroup>
</h:form>

【问题讨论】:

    标签: jsf-2 bean-validation hibernate-validator


    【解决方案1】:

    来自堆栈跟踪:

    at com.myapp.beans.DepartmentBean.addOrUpdateDepartment(DepartmentBean.java:105)
    ...
    at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
    

    这意味着无论如何都会调用您的 JSF bean 操作方法,而这应该被空 name 字段上的验证约束阻止,并且您应该在 &lt;h:message&gt;&lt;h:messages&gt; 中看到验证错误表格。

    这只能意味着您已将immeditate="true" 放在命令按钮/链接上,这将导致在表单处理中跳过所有不具有此属性的输入组件:

    <h:commandButton ... immediate="true" />
    

    或者您在 web.xml 中有此上下文参数,这将跳过对空字段的验证:

    <context-param>
        <param-name>javax.faces.VALIDATE_EMPTY_FIELDS</param-name>
        <param-value>false</param-value>
    </context-param>
    

    或者您在视图中通过以下标记禁用了 bean 验证:

    <f:validateBean disabled="true" />
    

    确保你没有它们。


    更新:根据您的更新,您犯了一个典型的错误:您将提交按钮的形式与输入字段不同。提交按钮需要与您希望随提交一起发送的输入字段采用相同的形式。

    【讨论】:

    • 奇怪的是我没有这两种猜测,还有其他想法吗?
    • 好吧,显然输入组件的过程验证阶段完全被跳过了。命令按钮上没有immediate="true" 吗?
    • 您的命令按钮采用不同的形式。当然它不会提交另一个表单的输入。将输入和命令放在 same 形式中。奇怪的是,这正是您今天answered 对另一个有类似问题的问题所提出的问题,并且还在comment 中向我询问确认...
    猜你喜欢
    • 1970-01-01
    • 2011-06-08
    • 2018-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-02
    • 1970-01-01
    相关资源
    最近更新 更多