【问题标题】:Hibernate: Execute custom logic and SQL statements on Insert or UpdateHibernate:在插入或更新时执行自定义逻辑和 SQL 语句
【发布时间】:2015-07-31 23:56:45
【问题描述】:

我正在使用旧数据库,每当有内容保存到数据库的其中一个表中时,我都需要执行一些自定义逻辑。这包括检查多个字段以查看发生了哪些类型的数据更改、使用适当的更改状态更新字段、更新表中的其他行,然后最后插入新行或更新现有行。

显然,这远远超出了@SQLInsert 或@SQLUpdate 注释所能做的。实现这一目标的最佳方法是什么?我需要在即将保存对象时调用一些东西,执行一些手动 SQL 调用,然后取消内置保存功能,因为我们会手动处理它。

【问题讨论】:

    标签: java hibernate groovy sql-update sql-insert


    【解决方案1】:

    您可以为此使用自定义事件侦听器。请参阅http://grails.github.io/grails-doc/2.5.x/guide/single.html#eventsAutoTimestamping(自定义事件监听器部分)。

    一个例子是:

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

    课程准备就绪后,别忘了注册。在 Bootstrap 的 init 闭包中,可以添加:

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

    如果您定义了多个数据源,您可能需要在调用each 方法之前过滤它们。

    【讨论】:

    • 乍一看它应该可以工作,不幸的是,我正在处理其中一个表中的@EmbeddableCollection 集合,并且对此集合的更新不会触发这些事件。它似乎只触发 pre-collection-recreate、pre-collection-remove 和 pre-collection-update Hibernate 事件,不幸的是,据我所知,它们的处理程序似乎没有办法取消实际更新。
    猜你喜欢
    • 2011-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-05
    相关资源
    最近更新 更多