2011-08-09 102 views
6

我想知道這個簡單問題的答案。創建實體規則

當我創建一個實體對象,我想限制一個屬性的設置(例如我不想讓任何人設置一個整數值小於1的屬性),我應該在這個屬性的setter還是應該在處理這些對象的類中檢查後者的限制?一般來說,我可以實現getter和setter,但是隻要我的getter返回並設置set屬性,我就可以實現嗎?

我知道在java中有一些規則(代碼約定),所以我不想破壞它們中的任何一個。

在此先感謝,希望我的問題對我可能犯的任何語法錯誤都足夠清楚和抱歉:/。

回答

6

是的getters/setters對此很有用。

例如:

public void setAge(int age){ 
if(age < 0){ 
    throw new IllegalArgumentException("Invalid age : " + age); 
    //or if you don't want to throw an exception you can handle it otherways too 
} 
} 

您也可以使用Java-EE的Bean Validators

public class Person{ 

    @Min(value = 0) 
    @Max(value = 99) 
    private Integer age; 

    //some other code 
} 
+0

謝謝!您的幫助非常感謝,並且很高興知道其他方法:) – VaclavDedik

+0

歡迎您:) –

1

這是獲得者和制定者的目標。

如果我們不能在這些方法中添加一些行爲,那麼......爲什麼我們不使用公共屬性?

2

我的首選方法是使用JSR 303(Bean驗證API),以確保該類的屬性是有效的。

在setter中執行驗證是完全可以的,但這並不總是一種理想的方法。有可能會混淆不相關的多個上下文的需求。例如,您的某些屬性決不能從用戶界面設置,而應該在被保留之前由服務計算。在這種情況下,將這個邏輯放在setter中是不可取的,因爲你需要知道setter被調用的上下文;您需要在UI層和持久層中應用不同的規則。 JSR 303允許您使用驗證組來區分這些問題,以便您的UI驗證組與您的持久性驗證組不同。

在JPA 2.0中,當您使用的是由JSR 303的驗證評估約束註釋類,持久化提供商可以自動評估對PrePersistPreUpdatePreRemove這些限制(通常沒有這樣做;見下文)的生命週期事件實體。要在您的JPA提供程序中執行實體驗證,您必須在persistence.xml文件中指定validation-mode元素或javax.persistence.validation.mode屬性;值必須是AUTO(默認值)或CALLBACK(而不是NONE)。

Bean驗證提供程序的存在足以確保在JPA實體生命週期事件上進行驗證,因爲默認值爲AUTO。在Java EE 6應用程序服務器中,您可以默認獲得此信息; Glassfish使用Hibernate Validator的JSR 303的RI實現,而且EclipseLink也可以很好地工作。

CALLBACK模式將允許您覆蓋觸發生命週期事件時要應用的驗證組。默認情況下,默認的Bean驗證組(Default)將針對更新和持久事件進行驗證;刪除事件不涉及任何驗證。 CALLBACK模式允許您使用屬性javax.persistence.validation.group.pre-persist,javax.persistence.validation.group.pre-updatejavax.persistence.validation.group.pre-remove爲這些事件指定不同的驗證組。

請記住,雖然我上面發佈的Bean Validation API文檔鏈接來自Java EE 6 API文檔,但可以在Java EE容器之外使用JSR 303驗證。

+0

順便說一下,JSR 303的參考實現是Hibernate Validator框架。請參閱:http://www.hibernate.org/subprojects/validator.html – MicSim

0

吸氣劑和吸附劑非常適合添加限制,就像Jigar Joshi在他的回答中所做的一樣。這樣,您可以立即獲得反饋,並在引入問題時處理問題。

另一個解決方案是使用對象驗證(類似於JSR-303實現),它允許您使用最小值和最大值對字段進行註釋。像

@Min(value=1) 
private int myvalue; 

東西然後你就可以一氣呵成驗證整個對象並獲取所有信息,如果您有其他的限制領域。這在任何地方顯然都沒有用,但如果它符合你的需要,它是一種選擇。

最後,當你說「實體」時,我想到了存儲在數據庫中或與ORM工具相關的東西。如果是這樣的話,你會想要小心你在吸氣劑中的作用。例如,如果您在getter中執行延遲初始化,則某些ORM供應商會將實體標記爲髒,並嘗試將其刷新到數據庫,可能會導致意外寫入。