繁体   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