Including Grails save () in a domain object

I am writing a Grails plugin and I need to connect to the save () method of the domain in order to execute some logic after saving. I need to do this through several domain classes. I try to avoid events in sleep mode in cases when the plugin user does not use sleep mode with GORM.

I have tried many things, but below I think that I would have a better chance of working. In all cases, grailsSave is NULL. How can i do this?

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" //... } } } 

I have the following set in my class * Plugin.groovy:

 def dependsOn = [domainClass: '1.1 > *', hibernate: '1.1 > *'] def loadAfter = ['hibernate'] 
+7
grails groovy grails-plugin
source share
6 answers

I was not able to successfully get a link to save () methods during plugin / application initialization; I do not know why. Instead, I decided to create a listener for hibernation events after inserting, updating, and deleting. This post from Sean Hartsock regarding the audit audit plugin was ideal for this.

Here's the gist of the listener:

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

Then in * 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 } 

Pretty simple at the end of the day ...

+6
source share

Three different save versions have been added to the metaclass.

 save(Map) save(Boolean) save() 

Who are you calling in your testing? You need to add a code to each.

Another thing to check is whether your plugin is running after the hibernate plugin, which adds three methods to metaClass

amuses

Lee

+2
source share

Take a look at the Falcone Util plugin. This plugin allows you to connect to Hibernate events (see the documentation at the bottom of the page). I don’t know, this is exactly what you want, but you can get some tips.

Ps! I do not think the plugin works with Grails 1.2.

+2
source share

This is a problem of premature optimization: older versions of Groovy are seriously fined on MetaClass manipulation, and therefore GORM does not add all its magic until it finds a need.

The easiest solution is to connect your plugin to GORM Labs (I work there). An alternative solution is to start the Missing method manually (which will duplicate the work that I did). For more information on how I did this, see the GORM Labs documentation.

+2
source share

Wouldn't it be better to add the service class to which the unit of work belongs? That the usual Spring / Grails logic would have that logic. You do not need to change the save at all.

+1
source share

Additional GORM methods are lazily initialized the first time you call any of them. To initialize them in doWithDynamicMethods , simply call one of the static methods in the domain class (s):

 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[]) //... } } 

Now your save () method will be available. Since this is called at startup, one account should not be a big problem.

+1
source share

All Articles