我试图在 Grails 中动态创建域对象,但遇到了这样的问题:对于引用另一个域对象的任何属性,元属性告诉我它的类型是“java.lang.Object”,而不是预期的类型。

例如:

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

是域类的开始,它引用另一个域类“Site”。

如果我尝试使用此代码(在服务中)动态查找此类的属性类型:

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 实例查找类,它会起作用,但我想避免这种情况。

有帮助吗?

解决方案

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

应用程序编程接口:

其他提示

由齐格弗里德提供上述答案变得过时周围某处的Grails 2.4。 ApplicationHolder是过时的。

现在,你可以在 domainClass 属性,每个域类都有获得真正的类型名称。

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

注意:此答案不是直接到这个问题,但涉及足够IMO

我敲我的头在墙上,地上,周围的树木,试图解决一个收藏协会的“通用型”的时候:

class A {
    static hasMany = {
        bees: B
    }

    List bees
}

原来最简单的,但声音的方式是单纯的(并且其我没有尝试,但在3小时后):

A.getHasMany()['bees']
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top