2009-12-24 14 views
7

मैं एक grails प्लगइन लिख रहा हूं और मुझे बचाने के बाद कुछ तर्क करने के लिए डोमेन सेव() विधि में हुक करने की आवश्यकता है। मुझे इसे कई डोमेन कक्षाओं में करने की ज़रूरत है। मैं उन मामलों में हाइबरनेट घटनाओं से बचने की कोशिश कर रहा हूं जहां एक प्लगइन उपयोगकर्ता GORM के साथ हाइबरनेट का उपयोग नहीं कर रहा है।Grails में ऑब्जेक्ट डोमेन ऑब्जेक्ट सेव()

मैंने कई चीजों की कोशिश की है लेकिन नीचे मुझे लगता है कि काम करने का सबसे अच्छा मौका होना चाहिए था। सभी मामलों में grailsSaveशून्य है। मैं यह कैसे कर सकता हूँ?

def doWithDynamicMethods = { ctx -> 
    application.domainClasses.each { dc -> 
     def grailsSave = dc.metaClass.pickMethod('save', [Map] as Class[]) 

     domainClass.metaClass.save = { Map params -> 
     grailsSave.invoke(delegate, [params] as Object[]) 
     println "Saved object, now do my thing" 
     //... 
     } 
    } 
} 

मैं अपने * Plugin.groovy वर्ग में सेट निम्नलिखित है:

def dependsOn = [domainClass: '1.1 > *', hibernate: '1.1 > *'] 
def loadAfter = ['hibernate'] 

उत्तर

6

मैं प्लगइन/ऐप प्रारंभ के दौरान सहेजने() विधियों का सफलतापूर्वक संदर्भ प्राप्त करने में असमर्थ था; मुझे नहीं पता क्यों। इसके बजाय, मैंने डालने, अद्यतन करने और हटाने के बाद हाइबरनेट घटनाओं के लिए श्रोता बनाने का निर्णय लिया। ऑडिट लॉगिंग प्लगइन के संबंध में शॉन हार्ट्सॉक द्वारा यह post ऐसा करने के लिए एक आदर्श प्राइमर था।

class MyListener implements PostInsertEventListener, PostUpdateEventListener, PostDeleteEventListener, Initializable { 

     public void onPostInsert(final PostInsertEvent event) { 
      // logic after insert 
      return 
     } 

     public void onPostUpdate(final PostUpdateEvent event) { 
      // logic after update 
      return 
     } 

     public void onPostDelete(final PostDeleteEvent event) { 
      // logic after delete 
      return 
     } 


     public void initialize(final Configuration config) { 
      return 
     } 
    } 
फिर * GrailsPlugin.groovy में

:

def doWithApplicationContext = { applicationContext -> 

    // add the event listeners for reindexing on change 
    def listeners = applicationContext.sessionFactory.eventListeners 
    def listener = new MyListener() 

    ['postInsert', 'postUpdate', 'postDelete'].each({ 
     addEventTypeListener(listeners, listener, it) 
    }) 

} 


// copied from http://hartsock.blogspot.com/2008/04/inside-hibernate-events-and-audit.html 
private addEventTypeListener(listeners, listener, type) { 
    def typeProperty = "${type}EventListeners" 
    def typeListeners = listeners."${typeProperty}" 

    def expandedTypeListeners = new Object[typeListeners.length + 1] 
    System.arraycopy(typeListeners, 0, expandedTypeListeners, 0, typeListeners.length) 
    expandedTypeListeners[-1] = listener 

    listeners."${typeProperty}" = expandedTypeListeners 
} 

दिन के अंत में काफी सरल ...

+0

शॉन और उनके लेखापरीक्षा लॉगिंग प्लगइन चट्टानों। –

+0

साझा करने के लिए धन्यवाद! मैं इसे अपने आप को देखने के लिए आलसी रहा हूँ। – Kimble

1

इस सबसे अच्छी सेवा वर्ग है कि काम की इकाई का मालिक नहीं जोड़ा जा सकते हैं? यही वह जगह है जहां सामान्य वसंत/Grails मुहावरे इस तरह के तर्क होगा। आपको बचत को बिल्कुल संशोधित करने की आवश्यकता नहीं है।

+0

हालांकि मैं दूसरों द्वारा उपयोग किए जाने वाले प्लगिंग का निर्माण कर रहा हूं। मेरा तर्क बहुत अच्छी तरह से एक सेवा में हो सकता है लेकिन जिस बिंदु पर इसे आग लगाना है उसे बचाने पर है। धन्यवाद – mbrevoort

+0

सीधे किसी अन्य स्तर पर डोमेन से संबंधित तर्क का एक समूह प्रस्तुत करने का विचार वसंत में सबसे बड़ी परेशानियों में से एक है, और यही वजह है कि जावा को जटिलता को मजबूत करने की प्रतिष्ठा है। –

+0

यह जानने के लिए एक व्यक्तिगत डोमेन ऑब्जेक्ट कैसा होता है जब यह काम की एक बड़ी इकाई का हिस्सा होता है और जब यह नहीं होता है? – duffymo

2

सहेजें metaClass को जोड़ा गया के तीन अलग संस्करण हैं,

save(Map) 
save(Boolean) 
save() 

आप कौन-सी अपने परीक्षण में बुला रहे हैं? आपको प्रत्येक को कोड जोड़ना होगा।

जाँच करने के लिए एक और बात अपने प्लगइन Falcone Util प्लगइन पर एक नजर है हाइबरनेट प्लगइन जो metaClass

चियर्स

ली

+0

धन्यवाद ली, मुझे लगता है कि मुझे हाइबरनेट के बाद लोड करने के लिए प्लगइन को मजबूर करने में समस्या हो रही है। यदि मैं doWithDynamicMethods में चलाता हूं तो pickMethod को कॉल करने के सभी प्रयास शून्य हैं। अगर मैं grails कंसोल में चलाता हूं तो वे शून्य नहीं होते हैं। मेरे पास यह मेरी प्लगइन में है लेकिन कोई भाग्य नहीं: def निर्भर करता हैऑन = [डोमेन क्लास: '1.1> *', हाइबरनेट: '1.1> *'] डीफ़ लोडएफ़टर = ['हाइबरनेट'] – mbrevoort

+0

हमम लोड वह है जिसे आप चाहते हैं - क्या इसे स्थिर लोड के बाद = ['हाइबरनेट'] – leebutts

+0

स्थैतिक काम नहीं करता है। अजीब मैंने अभी देखा है कि रॉबर्ट फिशर ने अपने जीओआरएम लैब्स प्लगइन में सेव() को समान चीजों को करने की कोशिश की थी, लेकिन पिछले संस्करणों में कोड को टिप्पणी की थी और हाल ही में मौजूद नहीं है। इस दृष्टिकोण से अलग तरीके से संपर्क करने के लिए कोई विचार? – mbrevoort

2

को तीन तरीकों कहते हैं के बाद से चल रहा है या नहीं। यह प्लगइन आपको हाइबरनेट घटनाओं में हुक करने की अनुमति देता है (पृष्ठ के नीचे दस्तावेज़ देखें)। मुझे नहीं पता कि यह वही है जो आप चाहते हैं, लेकिन आपको कुछ संकेत मिल सकते हैं।

Ps! मुझे नहीं लगता कि प्लगइन अभी तक Grails 1.2 के साथ काम करता है।

+0

धन्यवाद दोस्त, वह प्लगइन उत्कृष्ट दिखता है। अगर इस प्रकार की घटना क्षमता कोर में उपलब्ध थी तो भयानक होगा। – mbrevoort

2

यह वह जगह है

यहाँ श्रोता का सार है समयपूर्व अनुकूलन का एक मुद्दा: ग्रोवी के पुराने संस्करणों ने मेटा क्लास मैंगलिंग को गंभीरता से दंडित किया, और इसलिए जीओआरएम अपने सभी जादू को तब तक नहीं जोड़ता जब तक कि इसकी आवश्यकता नहीं होती।

सबसे आसान समाधान यह है कि आपकी प्लगइन निर्भर है कि GORM लैब्स पर (मैं इसके आसपास काम करता हूं)। वैकल्पिक समाधान मैन्युअल रूप से विधि को याद करने के लिए है (जो मैंने किया काम डुप्लिकेट करेगा)। मैंने इसे पूरा करने के विवरण के लिए GORM लैब्स दस्तावेज़ देखें।

1

अतिरिक्त GORM विधियों को किसी भी व्यक्ति को पहली कॉल पर आलसी शुरू किया गया है। उन्हें doWithDynamicMethods में प्रारंभ करने के लिए बस अपने डोमेन वर्ग (ते) पर स्थिर तरीकों में से एक फोन:

def doWithDynamicMethods = { ctx -> 

    application.domainClasses.each { dc -> 

     // call any static method to initialize dynamic gorm methods 
     dc.clazz.count() 

     def grailsSave = dc.metaClass.pickMethod('save', [Map] as Class[]) 
     //... 
    } 
} 

आपका save() विधि अब उपलब्ध हो जाएगा। चूंकि इसे शुरू करने के लिए कहा जाता है क्योंकि एक भी गिनती किसी समस्या का अधिक नहीं होना चाहिए।

संबंधित मुद्दे