14

Grails でドメイン オブジェクトを動的に作成しようとしていますが、別のドメイン オブジェクトを参照するプロパティについて、メタプロパティがその型が "java.lang.Object" であり、期待される型ではないことを示すという問題が発生しました。

例えば:

class PhysicalSiteAssessment {
    // site info
    Site site
    Date sampleDate
    Boolean rainLastWeek
    String additionalNotes
    ...

は、別のドメイン クラス「サイト」を参照するドメイン クラスの始まりです。

このコードを (サービスで) 使用して、このクラスのプロパティ タイプを動的に検索しようとすると、次のようになります。

String entityName = "PhysicalSiteAssessment"
Class entityClass
try {
    entityClass = grailsApplication.getClassForName(entityName)
} catch (Exception e) {
    throw new RuntimeException("Failed to load class with name '${entityName}'", e)
}
entityClass.metaClass.getProperties().each() {
    println "Property '${it.name}' is of type '${it.type}'"
}

その結果、Java クラスは認識されますが、Grails ドメイン クラスは認識されません。出力には次の行が含まれます。

Property 'site' is of type 'class java.lang.Object'
Property 'siteId' is of type 'class java.lang.Object'
Property 'sampleDate' is of type 'class java.util.Date'
Property 'rainLastWeek' is of type 'class java.lang.Boolean'
Property 'additionalNotes' is of type 'class java.lang.String' 

問題は、動的ルックアップを使用して一致するオブジェクトを見つけたいことです。たとえば、

def targetObjects = propertyClass."findBy${idName}"(idValue)

ここで、propertyClass はイントロスペクションによって取得されます。idName は検索するプロパティの名前 (必ずしもデータベース ID ではありません) であり、idValue は検索する値です。

それはすべてで終わります:

org.codehaus.groovy.runtime.InvokerInvocationException: groovy.lang.MissingMethodException: No signature of method: static java.lang.Object.findByCode() is applicable for argument types: (java.lang.String) values: [T04]

プロパティの実際のドメイン クラスを見つける方法はありますか? または、タイプが指定されていないドメイン クラスのインスタンス (タイプを持つプロパティ名のみ) を見つけるという問題に対する他の解決策でしょうか?

タイプ名が大文字のプロパティ名であるという規則を使用すると機能します(「サイト」->「サイト」) grailsApplication インスタンスを介してクラスを検索しますが、それは避けたいと思います。

4

4 に答える 4

16

Grails では、GrailsApplication インスタンスを介してドメイン モデルの一部のメタ情報にアクセスできます。そのように調べることができます:

import org.codehaus.groovy.grails.commons.ApplicationHolder
import org.codehaus.groovy.grails.commons.DomainClassArtefactHandler

def grailsApplication = ApplicationHolder.application
def domainDescriptor = grailsApplication.getArtefact(DomainClassArtefactHandler.TYPE, "PhysicalSiteAssessment")

def property = domainDescriptor.getPropertyByName("site")
def type = property.getType()
assert type instanceof Class

API:

于 2009-06-10T07:57:03.913 に答える
15

GrailsClassUtils.getPropertyType(clazz, propertyName)を使用できます

于 2011-05-25T06:37:56.793 に答える
3

Siegfried によって提供された上記の回答は、Grails 2.4 あたりで廃止されました。ApplicationHolder は廃止されました。

これで、すべてのドメイン クラスが持つdomainClassプロパティから実際の型名を取得できるようになりました。

entityClass.domainClass.getProperties().each() {
    println "Property '${it.name}' is of type '${it.type}'"
}
于 2015-07-14T19:26:29.340 に答える
0

注:この回答は質問に直接関係するものではありませんが、十分なIMOに関連しています。

コレクションの関連付けの「一般的なタイプ」を解決しようとしているときに、壁、地面、周囲の木に頭をぶつけていました。

class A {
    static hasMany = {
        bees: B
    }

    List bees
}

最も簡単でありながら健全な方法は単なるものであることが判明しました(そして、私は試しませんでしたが、3時間後に):

A.getHasMany()['bees']
于 2012-02-17T14:13:53.123 に答える