Grails getSomething(int i)方法无法编译

时间:2008-12-27 23:31:21

标签: spring grails groovy

有人能告诉我为什么这个Grails域类不会编译(在运行时)?

class Person {
    String name

    String getSomething(int i) {
    }
}

我使用grails run-app

运行时出现此错误
2008-12-27 15:26:33.955::WARN:  Failed startup of context org.mortbay.jetty.webapp.WebAppContext@187e184{/asrs2,C:\Steve\asrs2/web-app}
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'pluginManager' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Invocation of init method failed; nested exception is java.lang.NullPointerException
        at java.security.AccessController.doPrivileged(Native Method)
        at RunApp_groovy$_run_closure2_closure7.doCall(RunApp_groovy:67)
        at RunApp_groovy$_run_closure2_closure7.doCall(RunApp_groovy)
        at Init_groovy$_run_closure6.doCall(Init_groovy:131)
        at RunApp_groovy$_run_closure2.doCall(RunApp_groovy:66)
        at RunApp_groovy$_run_closure2.doCall(RunApp_groovy)
        at RunApp_groovy$_run_closure1.doCall(RunApp_groovy:57)
        at RunApp_groovy$_run_closure1.doCall(RunApp_groovy)
        at gant.Gant.dispatch(Gant.groovy:271)
        at gant.Gant.this$2$dispatch(Gant.groovy)
        at gant.Gant.invokeMethod(Gant.groovy)
        at gant.Gant.processTargets(Gant.groovy:436)
        at gant.Gant.processArgs(Gant.groovy:372)
Caused by: java.lang.NullPointerException
        at java.lang.Class.isAssignableFrom(Native Method)
        ... 13 more

如果我将方法getSomething更改为doSomething,那么它可以正常工作。 getSomething(int i)以某种方式被视为bean方法吗?

跟进:这是Grails bug,将在1.2中修复。

5 个答案:

答案 0 :(得分:7)

嗯,你有两个问题:

  1. Grails中的域类尝试确保每个属性在启动期间都有getter和setter。它通过查找所有getter并确保存在适当的setter来实现此目的。所以,如果你有一个getSomething(),你必须有一个setSomething(def something),即使在类中没有属性“something”。实际上,通过创建getSomething()函数,你暗示有这样的属性,你也必须创建一个setSomething()。

  2. Getters 不接受参数。你的。现在我意识到你在写这篇文章时并不认为这是一个“吸气剂”,但是你的命名使它成为一个。

  3. 最好的选择?不要使用“get”或“set”或“is”前缀,除非你真的在制作一个可以获取和设置的完整属性。我也会避免在Domain类中“查找”,因为它有自己的一组生成方法。

答案 1 :(得分:5)

几个笔记......

  • 如果您提供二传手,您也不必提供吸气剂。反之亦然。你真正做的是覆盖Groovy附加的默认访问器方法。如果您愿意,可以覆盖一个而不是另一个。
  • 如果你在你的域类中以'find'开头的方法没有问题,因为动态查找器方法实际上是静态方法添加(并且它们都以'findBy *'开头)。
  • 瞬态解决方案不起作用。使'某事'成为一个瞬态值并不能帮助你获得一个带有错误参数签名的getter这一事实。动态键入返回值时也是如此。
  • 这不是Groovy的问题,而是Grails。

我认为解决方案是将您的方法名称从 getSomething 更改为 findSomething 或您认为不符合约定的任何内容。以下工作正常:

class Person {
    String name

    String findSomething(int i) {
    }
}

答案 2 :(得分:4)

不要将方法定义为具有返回类型,而是尝试使用def

class Person {
    String name

    def getSomething(int i) {
        // foo
    }
}

另一种解决方案可能是将something定义为瞬态(假设您实际上没有名为'某事'的属性):

class Person {
    String name

    static transients = ['something']

    String getSomething(int i) {
        // foo
    }
}

答案 3 :(得分:1)

在回答这个问题之前,让我告诉你我的环境:
Grails 1.0.4
Java 1.6.0_10-beta
Groovy 1.6-RC-1
在Windows Vista计算机上

在grails中,动态get方法在运行时为域类中的所有字段添加。对于问题中提到的Person类,将在运行时添加一个getName()方法,允许人们使用它来定义它。现在问题是,getSomething(int i)是你的类中没有一个名为String的字段。如果你尝试添加一个名为getName(int i)的方法,它将没有任何问题或者你添加一个字符串的东西 那么getSomething()方法就可以了。

我希望暂时解决这个问题...我会继续寻找并发布有关确切工作的更新。

答案 4 :(得分:1)

我得出结论,这是Grails的一个错误。我创建了GRAILS-3760,已在Grails 1.1.2中修复。