Как получить тип (класс) свойства объекта домена Grails? - PullRequest
14 голосов
/ 10 июня 2009

Я пытаюсь динамически создавать доменные объекты в 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]

Есть ли способ найти фактический класс домена для свойства? Или может быть какое-то другое решение проблемы поиска экземпляра класса домена, тип которого не указан (только имя свойства, имеющее тип)?

Это работает, если я использую соглашение о том, что имя типа - это имя свойства с большой буквы ("site" -> "Site") для поиска класса через экземпляр grailsApplication, но я бы хотел этого избежать.

Ответы [ 4 ]

15 голосов
/ 10 июня 2009

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:

13 голосов
/ 25 мая 2011

Вы можете использовать GrailsClassUtils.getPropertyType (clazz, propertyName)

2 голосов
/ 14 июля 2015

Ответ выше, предоставленный Зигфридом, устарел где-то около Грааля 2.4. ApplicationHolder устарел.

Теперь вы можете получить реальные имена типов из свойства domainClass , которое есть у каждого класса домена.

entityClass.domainClass.getProperties().each() {
    println "Property '${it.name}' is of type '${it.type}'"
}
0 голосов
/ 17 февраля 2012

Примечание: этот ответ не имеет прямого отношения к вопросу, но имеет отношение к ИМО.

Я ударился головой о стену, землю и окружающие деревья, когда пытался определить «общий тип» ассоциации коллекций:

class A {
    static hasMany = {
        bees: B
    }

    List bees
}

Оказалось, что самый простой и в то же время здравый способ был простым (и который я не пробовал, но через 3 часа):

A.getHasMany()['bees']
...