簡體   English   中英

為什么域類中字段上的作用域修飾符會阻止驗證?

[英]Why do scope modifiers on fields in domain classes prevent validation?

我只是從Grails(來自Rails)開始,我注意到Grails確實似乎並不喜歡域類中字段的作用域修飾符。

我了解到,默認情況下,域類中所有未作用域的字段都是public,但是如果您實際上將其聲明為public,Grails將不會對其進行驗證。

class Person {
  public String firstName
  public String middleName
  public String lastName
}

如果添加約束,則在調用validate()時,Grails將拋出NotReadablePropertyException異常。

class Person {
  public String firstName
  public String middleName
  public String lastName

  static constraints = {
     middleName nullable: true
  }
}

但是,如果您刪除公共聲明,則一切正常。

有人可以通過域類的作用域解釋幕后發生的事情嗎? 很難理解為什么顯式聲明已經公開的東西會破壞框架。 我猜您也不想聲明任何“私有”,盡管如果可以將不應該直接操作的字段隱藏在域類的使用者中,那將是很好的選擇。

當您將一個字段添加到沒有范圍修飾符的Groovy類中時,更多的是推斷它是公開的,而不是實際公開的。 編譯器將字段轉換為私有字段,並為其生成一個公共的getter和setter,盡管它不會覆蓋您編寫的getter或setter。 這很方便,因為您以后可以編寫getter和/或setter來實現業務邏輯並且不影響調用方。

但是,一個公共領域(被稱為“公共”)就是一個公共領域。 沒有生成的getter或setter。 我建議使用反編譯器來查看實際效果-在src / groovy中創建一個簡單的POGO,例如

class Thing {
   String realProperty
   public String fieldButNotProperty
}

並使用http://jd.benow.ca/或其他反編譯器打開.class文件。

GORM會自動假定類型化屬性是持久性的,除非您在transients列表中排除了某些屬性。 該類型是必需的,因此它知道如何持久存儲數據,並且諸如def name類的屬性將被忽略。 從這個意義上講,屬性類似於JavaBean屬性-匹配的getter / setter對。

Hibernate不支持Groovy,也不知道幕后情況-它只是在持久化過程中調用您的getter和setter來設置和訪問字段數據。 因此,使用Groovy編譯器添加這些代碼后,Hibernate便可以輕松保留Grails中的POGO。 您可以自己執行此操作-添加具有正確名稱和數據類型(例如String getName()void setName(String name)的getter和setter,即使您不使用值對它也將被視為持久屬性。 。

出現NotReadablePropertyException的原因是,沒有getter可以調用您的“屬性”。 即使您的字段可以完全訪問,您也已對GORM和Hibernate有效地隱藏了它們。

如果添加約束,則在調用validate()時,Grails將拋出NotReadablePropertyException異常。

以前從未注意到這一點,聽起來像個bug

如果有一個不錯的選擇,那就是可以對域類的使用者隱藏不應直接操作的字段,那將是很好的選擇。

如果要防止直接訪問屬性,只需添加一個getter和setter即可。 在下面的(人為)示例中,我確保始終將名稱讀/寫為大寫字符串。

class Person {
  public String firstName
  public String middleName
  public String lastName

  public void setFirstName(String name) {
    this.firstName = name.toUpperCase()
  }

  public String getFirstName() {
    return this.firstName.toUpperCase()
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM