Метод Grails getSomething (int i) не компилируется

Может кто-нибудь сказать мне, почему этот класс домена Grails не будет компилироваться (во время выполнения)?

class Person {
    String name

    String getSomething(int i) {
    }
}

Я получаю эту ошибку, когда я запускаю с grails run-app:

2008-12-27 15:26:33.955::WARN:  Failed startup of context [email protected]{/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?

Follow after. Это ошибка Grails, которая будет исправлена ​​в 1.2.

Ответ 1

Я пришел к выводу, что это ошибка с Grails. Я создал GRAILS-3760, который был исправлен в Grails 1.1.2.

Ответ 2

У вас есть две проблемы:

  • Классы доменов в Grails пытаются убедиться, что каждое свойство имеет getter и setter во время запуска. Он делает это, ища все геттеры и убедившись, что существует соответствующий сеттер. Итак, если у вас есть getSomething(), вы должны иметь setSomething (def something), , даже если в классе нет свойства "что-то". Действительно, создав функцию getSomething(), вы подразумеваете, что существует такое свойство, и вы также должны создать setSomething().

  • Getters не принимают аргументы. Твой. Теперь я понимаю, что вы не думали, что это был "геттер", когда вы его написали, но ваше написание его делает его одним.

Лучше всего? Не используйте префиксы "get" или "set" или "is", если вы действительно не делаете полное свойство, которое можно получить и установить. Я бы также избегал "находить" в классах Домен, так как у него есть собственный набор сгенерированных методов.

Ответ 3

Несколько заметок...

  • Если вы предоставляете сеттер, вам также не нужно предоставлять получателю. И наоборот. То, что вы действительно делаете, переопределяет методы доступа по умолчанию, которые Groovy прикрепляет для вашего. Вы можете переопределить один, а не другой, если хотите.
  • Нет проблем, если вы создадите метод в своем классе домена, начиная с "find", потому что методы динамического поиска на самом деле являются добавлением статического метода (и все они начинаются с "findBy *" ).
  • Решение переходных процессов не будет работать. Создание "чего-то" переходного значения не помогает тому факту, что у вас есть геттер с неправильной сигнатурой параметра. То же самое, когда вы динамически вводите возвращаемое значение.
  • Это не проблема для Groovy, но для Grails.

Я думаю, что решение состоит в том, чтобы изменить имя метода из getSomething, чтобы найти что-то или что бы вы ни хотели, не противоречит конвенции. Следующее прекрасно работает:

class Person {
    String name

    String findSomething(int i) {
    }
}

Ответ 4

Вместо того, чтобы определять метод как имеющий тип возвращаемого значения, попробуйте использовать только def:

class Person {
    String name

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

Другим решением может быть определение something как переходного процесса (при условии, что на самом деле у вас нет свойства, называемого "что-то" ):

class Person {
    String name

    static transients = ['something']

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

Ответ 5

Прежде чем ответить на вопрос, позвольте мне рассказать вам о моей среде:
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), он будет работать без каких-либо проблем или если вы добавите поле String something то будет работать метод getSomething().

Надеюсь, это пока решает проблему... Я бы продолжил искать и публиковать обновления о точной работе в ближайшее время.