Custom Persistence Listener in Mongodb Grails plugin



Mongodb grails persistance listeners to assign default properties
Mongodb doesn't support extending the base class to assign values to common properties like updatedOn, createdOn etc.
Hibernate has support to extend the class to a domain and assign the properties. In grails mongodb we can acheive this using Grails persistance listeners.
1. Install mongodb plugin in grails (BuildConfig.groovy).
compile "org.grails.plugins:mongodb:5.0.7.RELEASE"

2. Now Create Perstitance Listener by extending AbstractPersistenceEventListener in src/groovy. AbstractPersistenceEventListener will provide onPersistenceEvent and we can capture PreInsert, PreUpdate ... events
MongoPersistanceListener.groovy>
import org.grails.datastore.mapping.core.Datastore
import org.grails.datastore.mapping.engine.event.AbstractPersistenceEvent
import org.grails.datastore.mapping.engine.event.AbstractPersistenceEventListener
import org.grails.datastore.mapping.engine.event.PreDeleteEvent
import org.springframework.context.ApplicationEvent

import org.grails.datastore.mapping.engine.event.EventType

class MongoPersistanceListener extends AbstractPersistenceEventListener  {

    def springSecurityService

    public MongoPersistanceListener(final Datastore datastore, def springSecurityService) {
        super(datastore)
        this.springSecurityService = springSecurityService
    }
    @Override
    protected void onPersistenceEvent(final AbstractPersistenceEvent event) {
        def entity = event.entityObject
        switch(event.eventType) {
            case EventType.PreInsert:
                initDefaults(entity)
                break
            case EventType.PostInsert:
                break
            case EventType.PreUpdate:
                def currentUser = springSecurityService.getCurrentUser()
                event.entityObject.updatedBy = currentUser ? currentUser.id : 0;
                event.entityObject.updatedOn = new Date();
                break;
            case EventType.PostUpdate:
                break;
            case PreDeleteEvent:
                break;
            case EventType.PostDelete:
                break;
            case EventType.PreLoad:
                break;
            case EventType.PostLoad:
                break;
            case EventType.Validation:
                initDefaults(entity)
                break;
        }
    }

    @Override
    public boolean supportsEventType(Class eventType) {
        return true
    }

    void initDefaults(entity) {
        def currentUser = springSecurityService.getCurrentUser()
        if (entity.createdBy == null) {
            entity.createdBy = currentUser? currentUser.id : 0;
        }
        if (entity.createdOn == null) {
            entity.createdOn = new Date();
        }
        if (entity.updatedBy == null) {
            entity.updatedBy = currentUser? currentUser.id : 0;
        }
        if (entity.updatedOn == null) {
            entity.updatedOn = new Date();
        }
    }
}

3. Register this listener in Bootstrap.groovy init method
class BootStrap {

 def springSecurityService

    def init = { servletContext ->
        def ctx = Holders.grailsApplication.mainContext
        ctx.getBeansOfType(Datastore).values().each { Datastore d ->
            ctx.addApplicationListener( new MongoPersistanceListener(d, springSecurityService))
        }
    }
    def destroy = {
    }
}
This listener will be invoked when database event is triggered.

Categories: