2014-09-12 76 views
0

当Facelet的后台bean调用setLastName("Test!!!")时,虽然非alpha字符清晰地出现在方法参数中,但没有引发ConstraintViolationException。直到JPA实体合并为止,Bean验证不起作用

我设置了一个断点来验证setLastName被调用,我观察到JPA实体的lastName值更改。验证应该立即失败,是吗?不是。

稍后,当需要保存更改时,调用EntityManager#merge时,会引发ConstraintViolationException。

违反约束的列表:[ ConstraintViolationImpl {interpolatedMessage = 'error.spacesandletters', 的PropertyPath =姓氏,rootBeanClass =类 foo.bar.business.model.entity.authenticate.User, messageTemplate =” error.spacesandletters'}]

private String lastName; 

@Column(name="lastname", nullable=false, length=40) 
@Size(max=40) 
@NotNull 
@Basic(optional=false) 
@Pattern(regexp="[A-Za-z ]*", message="error.spacesandletters") 
public String getLastName() { return this.lastName; } 

public void setLastName(String lastName) { this.lastName = lastName; } 

所以我知道,验证是可用,这是在JPA工作前仍然存在。但由于某种原因,目前它不工作,用户#setLastName首先通过支持bean调用。我究竟做错了什么?

编辑#1:

我应该提到,我ChangePasswordBean工作只是有以下两个自定义注释罚款。

@NotEmpty @Password private String password1; 
@NotEmpty @Password private String password2; 

但是在这种情况下,支持bean的字段被注释。而在上面的示例中,支持bean指向其getter被注释的JPA实体。

编辑#2:

阅读BalusC的参考this other question后,他在想这个问题可能与一个known Mojarra bug that was fixed in v. 2.2.7我升级到钻嘴鱼科2.2.8-01。下面是在Wildfly启动日志条目:

17:41:51965 INFO [org.jboss.as.jsf(Server服务线程池 - 38)JBAS012615:激活以下JSF实现:钻嘴鱼科-2.2 .8-01,主]

不幸的是,我所描述的问题并没有消失。 JPA实体上的Bean验证注释不起作用,而JSF托管bean上的bean验证注释正在工作。

+0

只是一个疯狂的猜测 - 将移动注释从获取设置(或更好 - 字段本身)改变任何东西? – Deltharis 2014-09-12 22:24:34

+0

如果您的控制器中没有@Validation,验证只会发生在Persist/Merge级别。我对Facelet和JSF并不熟悉,但在验证方面应该与Spring-MVC类似。 – pms 2014-09-13 00:01:09

+0

@pmp:@Validation?没有这样的事情在javax.validation.constraints。附:我没有使用Spring。 – 2014-09-13 02:39:06

回答

1

这是正确的行为。如果您依赖基于JPA事件的验证,验证发生在更新前的事件。没有可用的生命周期事件,这会在单个字段的更改时触发。实际上,这只适用于仪器化的类,否则将无法拦截值的设置。此外,Bean Validation的核心框架是验证整个bean及其关联。因此,即使在Validation API中有validateValuevalidateProperty,主要验证例程是validate,它以bean /对象为参数。

因此,要回答你的问题:

验证应立即失败,是吗?

不,不应该。

你是否真的需要直接验证调用setter?有办法做到这一点,但它会涉及到编写一些自定义代码,你可能需要使用编译或运行时拦截框架。

+0

是的,当用户点击按钮时需要验证 - 而不是晚些时候,当实体被合并时。当调用支持bean的setter时,应该抛出ConstraintViolationException。这一切都适用于我的其他网页。区别在于这个特定的支持bean指向一个JPA实体。所以支持bean的getters/setters调用实体bean上的getters/setters。你是说我应该使用两组相同的注释,一组设置在实体bean上,另一组设置在辅助bean上? – 2014-09-13 20:28:06

+0

我使用其他信息编辑了我的问题。另一个支持bean的字段被注释验证很好,而指向JPA的支持bean有问题。 – 2014-09-13 20:45:56

+0

我知道你在OP没有使用'[jsf]'标签的时候回答了这个问题,但OP清楚地告诉他他使用了Facelets。正如OP预期的那样,JSF确实支持在验证阶段执行Bean验证。所以你的答案是根本错误的,你应该修改或删除它。 – BalusC 2014-09-14 07:41:41