2009-06-10 39 views
14

Tôi đang cố gắng tạo động các đối tượng miền trong Grails và gặp phải sự cố cho bất kỳ thuộc tính nào tham chiếu đến một đối tượng miền khác metaproperty cho tôi biết loại của nó là "java.lang.Object" và không phải kiểu dự kiến.Làm cách nào để nhận loại (lớp) của thuộc tính của đối tượng miền Grails?

Ví dụ:

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

là sự khởi đầu của một lớp miền, có sự tham khảo một lớp miền "Trang web".

Nếu tôi cố gắng để tự động tìm các loại tài sản cho lớp này bằng cách sử dụng mã này (trong một dịch vụ):

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}'" 
} 

thì kết quả là nó nhận ra các lớp Java, nhưng không phải là lớp miền Grails . Đầu ra chứa các dòng sau:

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' 

Vấn đề là tôi muốn sử dụng tra cứu động để tìm các đối tượng phù hợp, ví dụ: làm một

def targetObjects = propertyClass."findBy${idName}"(idValue) 

nơi propertyClass được lấy thông qua mẫn, idName là tên của tài sản để tìm kiếm (không nhất thiết phải là cơ sở dữ liệu ID) và idValue là giá trị cần tìm.

Tất cả đều kết thúc trong:

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] 

Có cách nào để tìm thấy những lớp miền thực cho bất động sản? Hoặc có thể một số giải pháp khác cho vấn đề tìm kiếm một thể hiện của một lớp miền có loại không được đưa ra (chỉ một tên thuộc tính có kiểu)?

Nó hoạt động nếu tôi sử dụng quy ước rằng tên loại là tên thuộc tính được viết hoa ("site" -> "Site") để tra cứu lớp thông qua cá thể grailsApplication, nhưng tôi muốn tránh điều đó.

Trả lời

15

Grails cho phép bạn truy cập một số thông tin meta của mô hình miền của bạn thông qua cá thể GrailsApplication. Bạn có thể nhìn nó theo cách đó:

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

Cảm ơn, điều đó có hiệu quả. Có một số tổng quan về API này ở đâu đó không? Tôi đã tìm kiếm một cái gì đó như thế này nhưng không thể tìm thấy nó. –

+0

Không có bất kỳ tài liệu tham khảo tốt nào mà tôi từng thấy ngoài javadocs (http://grails.org/doc/1.1/api/org/codehaus/groovy/grails/commons/DefaultGrailsApplication.html). Tôi cũng tìm thấy mã nguồn Grails rất hữu ích. Tôi cũng sử dụng loại công cụ này rất nhiều trong plugin xây dựng-kiểm tra dữ liệu để kiểm tra các ràng buộc đối tượng miền và tự động tạo các đối tượng thử nghiệm vượt qua các ràng buộc nếu bạn đang tìm kiếm các ví dụ (http://bitbucket.org/tednaleid/grails- kiểm tra dữ liệu/wiki/Trang chủ). –

+1

Thay vào đó, tôi đang gọi 'getDomainClass'. 'grailsApplication.getDomainClass (PhysicalSiteAssessment) .getPropertyByName ('site'). Type' –

0

Lưu ý: câu trả lời này không trực tiếp cho câu hỏi nhưng liên quan đủ IMO.

Tôi đã đập đầu tôi vào tường, mặt đất và cây cối xung quanh khi cố gắng giải quyết "kiểu chung chung" của một hiệp hội sưu tập:

class A { 
    static hasMany = { 
     bees: B 
    } 

    List bees 
} 

Hóa ra cách dễ nhất và chưa âm thanh là chỉ (và mà tôi đã không cố gắng nhưng sau 3 giờ):

A.getHasMany()['bees'] 
2

Câu trả lời trên được cung cấp bởi Siegfried trở nên lỗi thời ở đâu đó xung quanh Grails 2.4. ApplicationHolder đã lỗi thời.

Bây giờ, bạn có thể nhận tên loại thực từ thuộc tính miềnClass mà mọi lớp tên miền đều có.

entityClass.domainClass.getProperties().each() { 
    println "Property '${it.name}' is of type '${it.type}'" 
} 
Các vấn đề liên quan