2009-06-10 86 views
14

我試圖在Grails中動態創建域對象,並遇到了任何引用另一個域對象的屬性metaproperty告訴我它的類型是「java.lang.Object」而不是預期類型的​​問題。如何獲取Grails域對象的屬性的類型(類)?

例如:

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] 

有沒有辦法找到該屬性的實際域類?或者,也許有其他解決方案來找到一個沒有給出類型的域類的實例(只有一個屬性名稱具有類型)的問題?

它的工作原理是,如果我使用類型名稱爲propertyized的屬性名稱(「site」 - >「Site」)通過grailsApplication實例查找類的約定,但我想避免這種情況。

回答

15

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:

+0

謝謝,這是有效的。有沒有關於這個API的一些概述?我一直在尋找這樣的東西,但找不到它。 – 2009-06-10 23:24:37

+0

除了javadocs,我還沒有見過很好的參考資料(http://grails.org/doc/1.1/api/org/codehaus/groovy/grails/commons/DefaultGrailsApplication.html)。我也發現看看Grails源代碼非常有用。我還在構建測試數據插件中大量使用這種類型的東西來檢查域對象約束,並自動生成測試對象,以便在查找示例時傳遞約束(http://bitbucket.org/tednaleid/grails-測試數據/維基/家庭)。 – 2009-06-10 23:51:04

0

注意:這個答案不是直接的問題,而是涉及足夠的國際海事組織。

我敲我的頭在牆上,地上,試圖解決一個收藏協會的「通用型」時,周圍的樹木:

class A { 
    static hasMany = { 
     bees: B 
    } 

    List bees 
} 

原來最簡單的,但聲音的方式是單純的(和我沒有嘗試,但3小時後):

A.getHasMany()['bees'] 
2

以上由齊格弗裏德提供的答案變得過時了某處周圍的Grails 2.4。 ApplicationHolder已過時。

現在,您可以從domainClass獲得每個域類具有的屬性的實際類型名稱。

entityClass.domainClass.getProperties().each() { 
    println "Property '${it.name}' is of type '${it.type}'" 
}