2014-09-12 78 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