我需要捕获对某些数据的更改。我正在寻找以下细节:
我向我们的技术负责人建议,使用DB触发器可以轻松实现这一目标。有人告诉我,我们不控制数据库,也没有添加触发器的方法。
我目前正在使用带有自定义注释的Spring AspectJ,并包装我的服务以尝试捕获在调用“保存”方法后执行的生成的SQL(我认为解析SQL比尝试用Objects捕获要容易得多),但是我还没有找到捕获生成的SQL的方法。
我尝试了p6Spy并能够查看SQL并将其打印到控制台,但被告知我们无法将数据库驱动程序包装在PROD环境中。
是否缺少我想要的Spring课程?
编辑:我们正在使用Spring存储库来保存数据。
编辑2:我正在研究EventListener
,但是似乎无法让他们听我的活动。
@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
}
我在Listener
周围有断点,但从未到达断点。
This question似乎可以解决我的问题
答案 0 :(得分:0)
如果您完全确定每个插入/更新/删除操作都是通过JPA完成的,并且没有任何批量SQL,那么您应该看看envers
因此,您可以在要保留历史的实体(所有列)或实体列上使用@Audited
。
这将创建1个带时间戳更改的修订表(以及其他您想要的数据,例如进行更改的用户的uid),以及每个实体1个表,其中包含修改后的数据的旧值。
对于每个数据,您都可以检索历史记录和以前的值。
另一种方法是像更改数据捕获(CDC)工具一样在数据库上添加工具,并将这些事件推送到另一个数据存储库。
在+方面,将检测到所有内容(甚至本机SQL也直接在DB上运行)。缺点是,您的数据库需要正确支持这种工具。例如,kafka-connect之类的工具可以按您希望的方式工作,但是某些实现太简单了(例如,对于要进行select * from xxx
的过程的SAP hana而言)。
答案 1 :(得分:0)
我最终决定使用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