如何获取Grails域对象的属性的类型(类)?

时间:2009-06-10 06:32:29

标签: grails dynamic groovy metaobject

我正在尝试在Grails中动态创建域对象,并遇到这样的问题:对于引用另一个域对象的任何属性,metaproperty告诉我它的类型是“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]

有没有办法找到属性的实际域类?或者可能是其他一些解决问题的方法,即找到未给出类型的域类的实例(只有具有该类型的属性名称)?

如果我使用类型名称是大写的属性名称(“site” - >“Site”)来通过grailsApplication实例查找类,那么它可以工作,但我想避免这种情况。

4 个答案:

答案 0 :(得分: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:

答案 1 :(得分:13)

答案 2 :(得分:2)

Siegfried提供的上述答案在Grails 2.4附近已经过时了。 ApplicationHolder已过时。

现在,您可以从每个域类具有的 domainClass 属性中获取真实的类型名称。

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

答案 3 :(得分:0)

注意:这个答案不是直接针对这个问题,而是与IMO有关。

当我试图解决收藏协会的“通用类型”时,我正在把头撞到墙上,地面和周围的树上:

class A {
    static hasMany = {
        bees: B
    }

    List bees
}

原来最简单但最合理的方式仅仅是(我在3小时后没试过):

A.getHasMany()['bees']