2009-06-10 61 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}'" 
}