Сцепление в Объект области Grails сохраняет ()

Я пишу плагин чаш Грааля, и я должен сцепить в доменное сохранение () метод, чтобы сделать некоторую логику после сохранения. Я должен сделать это через несколько доменных классов. Я стараюсь избегать, в спящем режиме события в случаях, где сменный пользователь не использует, в спящем режиме с GORM.

Я попробовал многих, вещь, но ниже - то, что я думаю, должен был иметь лучшую возможность при работе. Во всех случаях 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']
7
задан mbrevoort 24 December 2009 в 17:16
поделиться

6 ответов

Я не смог успешно получить ссылку на методы save() при инициализации плагина/ приложения, не знаю почему. Вместо этого я решил создать слушатель для событий спящего режима после вставки, обновления и удаления. Эта запись Шона Хартсока относительно плагина Audit Logging была идеальным праймером для этого.

Вот суть слушателя:

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
}

Довольно просто в конце концов...

.
6
ответ дан 6 December 2019 в 15:23
поделиться

Посмотрите на плагин Falcone Util . Этот плагин позволяет подключаться к событиям Hibernate (см. Документацию внизу страницы). Не знаю, именно этого ли вы хотите, но вы можете получить несколько подсказок.

Пс! Я не думаю, что плагин работает с Grails 1.2.

2
ответ дан 6 December 2019 в 15:23
поделиться

Не лучше ли добавить это к классу обслуживания, которому принадлежит единица работы? Вот где обычная идиома Spring / Grails имеет такую ​​логику. Вам вообще не нужно изменять сохранение.

1
ответ дан 6 December 2019 в 15:23
поделиться

В метаКласс добавлены три разных версии сохранения,

save(Map)
save(Boolean)
save()

Какую из них вы вызываете при тестировании? Вам нужно будет добавить код к каждой из них.

Еще одна вещь, которую нужно проверить, работает ли ваш плагин после плагина hibernate, который добавляет три метода в metaClass

cheers

Lee

.
2
ответ дан 6 December 2019 в 15:23
поделиться

Это вопрос преждевременной оптимизации: старые версии Groovy серьезно наказали MetaClass, и поэтому GORM не добавляет всю свою магию до тех пор, пока не обнаружит в этом необходимости.

Самое простое решение - это иметь свою плагиновую зависимость от GORM Labs (я работаю с ней там). Альтернативным решением является запуск методаMissing вручную (который будет дублировать работу, которую я сделал). Смотрите документацию GORM Labs для получения подробной информации о том, как я это сделал.

.
2
ответ дан 6 December 2019 в 15:23
поделиться

Дополнительные методы 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 () будет доступен. Поскольку это вызывается при запуске, единичный подсчет не должен быть большой проблемой.

1
ответ дан 6 December 2019 в 15:23
поделиться