Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从Hibernate捕获生成的SQL_Java_Spring_Hibernate - Fatal编程技术网

Java 从Hibernate捕获生成的SQL

Java 从Hibernate捕获生成的SQL,java,spring,hibernate,Java,Spring,Hibernate,我需要捕获对某些数据的更改。我希望捕获以下详细信息: 表名称中发生的更改 列更改 先前值 更新值 我向我们的技术负责人建议,这可以通过DB触发器轻松实现。我被告知我们不控制数据库,也没有添加触发器的方法 我目前正在使用SpringAspectJ和一个自定义注释并包装我的服务,以尝试捕获在调用“save”方法后执行的生成的SQL(我认为解析SQL比尝试使用对象捕获要容易得多),但是我还没有找到捕获生成的SQL的方法 我尝试p6Spy并能够查看SQL并将其打印到控制台,但被告知无法在PROD环境中包

我需要捕获对某些数据的更改。我希望捕获以下详细信息:

  • 表名称中发生的更改
  • 列更改
  • 先前值
  • 更新值
  • 我向我们的技术负责人建议,这可以通过DB触发器轻松实现。我被告知我们不控制数据库,也没有添加触发器的方法

    我目前正在使用SpringAspectJ和一个自定义注释并包装我的服务,以尝试捕获在调用“save”方法后执行的生成的SQL(我认为解析SQL比尝试使用对象捕获要容易得多),但是我还没有找到捕获生成的SQL的方法

    我尝试p6Spy并能够查看SQL并将其打印到控制台,但被告知无法在PROD环境中包装db驱动程序

    有没有我错过的春季课程让这更容易

    编辑:我们正在使用Spring存储库来保存数据

    编辑2:我正在查看
    EventListener
    s,但是我似乎无法让他们收听我的事件

    @Component
    public class EventListner implements PreInserEventListener, PreUpdateEventListener {
       @Override
       @EventListener
       public boolean onPreUpdate(PreUpdateEvent event){
         // do something
    
         return false;
       }
    
       @Override
       @EventListener
       public boolean onPreInsert(PreUpdateEvent event){
         // do something
       }
       return false
    }
    
    我的
    监听器周围有断点,但从未触及



    看起来它可能解决了我的问题

    如果您完全确定每个插入/更新/删除都是通过JPA完成的,而没有任何批量SQL,那么您应该看看

    这样,您就可以在实体(所有列)或要保留历史记录的实体列上使用
    @Audited

    这将创建一个带有时间戳更改的修订表(以及您想要的其他数据,如做出更改的用户的uid),并为每个实体创建一个带有修改数据的旧值的表

    对于每个数据,您都可以检索历史记录和以前的值

    另一种方法是在数据库中添加工具,如更改数据捕获(CDC)工具,并将这些事件推送到另一个数据存储库。
    在+端,所有内容都将被检测到(即使是直接在数据库上运行的本机SQL)。缺点是,数据库需要正确支持此类工具。例如,像这样的工具可以按照您的意愿工作,但有些实现过于简单(例如,使用SAP hana时,流程将执行一个
    select*from xxx

    我最终决定使用Hibernate拦截器来完成这个任务。很好用

    public class TableInterceptor extends EmptyInterceptor {
    
       @Override
       public boolean onFlushDirty(Object entity, Serializable id,
                                   Object[] currentState, Object[] previousState,
                                   String[] propertyNames, Type[] types){
    
             // do comparison logic on fields and save to DB
       }
    }
    

    我引导拦截器将其注入我的
    LocalContainerEntityManagerFactoryBean

    我们对此进行了研究,但是,为我们正在审核的每个表创建一个阴影并不是我们的管理层想要做的事情。我正在查看
    @EventListeners
    ,看看是否可以捕获其中的值。如果您不想使用
    envers
    ,那么您可以使用fork envers项目将数据推送到您想要的地方。不确定它是简单的还是复杂的,但过程是存在的(过滤、旧值、新值),我想这是正确的。(1个要备份的实体可以手动执行,100个用于参数化,不是真的)是的,我们有可能“审核”1000个实体,您将更改存储在哪里?拦截SQL不会有任何帮助。你为什么不控制数据库呢?在编写应用程序时如何管理表更改。计划是解析INSERT和UPDATE语句,并将它们持久化到我们的审核表中。我们没有控制b/c,它是一个托管服务,因此触发器会对其他应用程序产生副作用。