4

この 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

メソッドを変更するgetSomethingdoSomething、機能します。getSomething(int i)どういうわけかBeanメソッドとして扱われていますか?

フォローアップ: これはGrails のバグで、1.2 で修正される予定です。

4

5 に答える 5

7

さて、2 つの問題があります。

  1. Grails のドメイン クラスは、起動時にすべてのプロパティに getter と setter があることを確認しようとします。これは、すべてのゲッターを検索し、適切なセッターが存在することを確認することによって行われます。したがって、 getSomething() がある場合は、 class にプロパティ「something」がなくても、 setSomething( def something ) が必要です。実際には、getSomething() 関数を作成することで、そのようなプロパティが存在することを暗示しており、setSomething() も作成する必要があります。

  2. ゲッターは引数を取りません。あなたはそうします。あなたがそれを書いたとき、これが「ゲッター」であるとは考えていなかったことに気づきましたが、あなたの命名はそれを1つにします。

最善の策?取得および設定できる完全なプロパティを実際に作成する場合を除き、「get」、「set」、または「is」プレフィックスを使用しないでください。また、生成されたメソッドの独自のセットがあるため、ドメインクラスでの「検索」も避けます。

于 2009-01-02T17:56:01.487 に答える
5

いくつかのメモ...

  • セッターを提供する場合、ゲッターも提供する必要はありません。およびその逆。実際に行っているのは、Groovy がアタッチしているデフォルトのアクセサー メソッドをオーバーライドすることです。必要に応じて、一方をオーバーライドできますが、他方はオーバーライドできません。
  • 'find' で始まるドメイン クラスのメソッドを作成しても問題はありません。これは、動的ファインダー メソッドは実際には静的メソッドの追加であるためです (そして、それらはすべて 'findBy*' で始まります)。
  • トランジェント ソリューションは機能しません。「何か」を一時的な値にすることは、間違ったパラメーター署名を持つゲッターを持っているという事実を助けません。戻り値を動的に入力する場合も同じです。
  • これは Groovy の問題ではなく、Grails の問題です。

解決策は、メソッド名をgetSomethingからfindSomethingに変更するか、慣習に反しないようにすることだと思います。以下はうまくいきます:

class Person {
    String name

    String findSomething(int i) {
    }
}
于 2009-01-22T16:52:05.813 に答える
4

メソッドを戻り値の型として定義する代わりに、以下を使用してみてくださいdef

class Person {
    String name

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

別の解決策は、一時的なものとして定義somethingすることです(実際に「何か」と呼ばれるプロパティがない場合):

class Person {
    String name

    static transients = ['something']

    String getSomething(int i) {
        // foo
    }
}
于 2009-01-21T22:45:34.697 に答える
1

質問に答える前に、私の環境について説明 します。WindowsVistaマシン上の
Grails 1.0.4
Java 1.6.0_10-beta
Groovy 1.6-RC-1

grailsでは、ドメインクラスのすべてのフィールドに動的getメソッドが実行時に追加されます。質問で取り上げられたPersonクラスの場合、実行時にgetName()メソッドが追加され、定義せずに使用できるようになります。ここで、getSomething(int i)の問題は、クラスにStringsomethingというフィールドがないことです。getName(int i)というメソッドを追加しようとすると、問題なく機能します。または、フィールドStringを追加すると、getSomething()メソッドが機能します。

これで当分の間問題が解決することを願っています...私は探し続け、正確な動作に関する最新情報をすぐに投稿します。

于 2008-12-28T01:58:57.923 に答える
1

これはGrailsのバグであると結論付けました。Grails1.1.2で修正されたGRAILS-3760を作成しました。

于 2010-01-15T18:43:06.867 に答える