简体   繁体   中英

Hibernate: Execute custom logic and SQL statements on Insert or Update

I'm working with a legacy database and I need to perform some custom logic whenever something gets saved to the database in one of its tables. This includes checking several fields to see what kind of data has changed, updating a field with the appropriate change status, updating other rows in the table and then finally inserting a new row or updating an existing row.

Obviously this is way more than the @SQLInsert or @SQLUpdate annotations can do. What would be the best approach to accomplish this? I need something that gets called when an object is about to be saved, does some manual SQL calls and then cancels the built-in save functionality since we took care if it manually.

You can use Custom Event Listeners for that. See http://grails.github.io/grails-doc/2.5.x/guide/single.html#eventsAutoTimestamping (section Custom Event Listeners ).

An example would be:

import org.grails.datastore.mapping.engine.event.PreUpdateEvent
import org.grails.datastore.mapping.engine.event.PreInsertEvent
import org.grails.datastore.mapping.engine.event.EventType
import org.springframework.context.ApplicationEvent
import org.grails.datastore.mapping.core.Datastore

class CustomSavePersistenceListener extends AbstractPersistenceEventListener {

   public CustomSavePersistenceListener(final Datastore datastore) {
      super(datastore)
   }

   @Override
   public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
      eventType in [ PreUpdateEvent, PreInsertEvent ]
   }

   @Override 
   protected void onPersistenceEvent(final AbstractPersistenceEvent event) {
      if (needsToBeCustomSaved(event.entityObject)) {
         doCustomSave(event.eventType, event.entityObject) 
         event.cancel()
      }
   }

   private boolean needsToBeCustomSaved(object) {
       // Your conditions to decide if needs special persistence
   }

   private void doCustomSave(EventType eventType, object) {
      // Your special persistence logic
   }
}

Once you have the class ready, don't forget to register it. In Bootstrap's init closure, you can add:

application.mainContext.eventTriggeringInterceptor.datastores.each { k, datastore ->
   applicationContext.addApplicationListener(new CustomSavePersistenceListener(datastore)
}

If you have more than one datasource defined, you might need to filter them before calling the each method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM