Java Web Application中的日志记录实体更改

时间:2010-09-20 05:35:15

标签: hibernate spring aop

我们对项目有一个要求,我们需要维护一些对应用程序中某些实体所做更改的历史记录。 Application是一个基于Struts,Spring和Hibernate的Java Web App。在这种情况下使用了哪种方法?

  • 各个表上的触发器是一个想法,但它们不易维护?也许它们也不应成为交易的一部分(如果触发器失败,则可以,但实体更新事务不应该失败)。
  • 使用AoP是因为它是一个贯穿各领域的问题,但必须非常精细,就像在实体更改时仅捕获值一样。 (所有编辑都没有相应的不同方法......许多编辑都发生在一个java方法中。)
  • 使用Hibernate事件监听器。

还有其他方法可以进行此类活动吗?

2 个答案:

答案 0 :(得分:4)

JBoss Envers支持试听和版本控制 - 看一看。

答案 1 :(得分:3)

因为你说

  

所有修改都没有相应的不同方法...... 在一个java方法中发生了很多编辑

即使你的方法只接收一个参数作为参数,你可以检索它的关系,AOP仍然是个好主意。我强烈建议你看看nice article

Hibernate文档本身说:

  

Hibernate Interceptor允许应用程序在保存,更新,删除或加载持久对象之前检查和/或操纵它们的属性。 这样做的一个可能用途是跟踪审核信息。

但它也说

  

确保您不存储会话特定状态,因为多个会话可能同时使用此拦截器

如果您使用Spring托管事务,则可以使用 sessionFactory.getCurrentSession();

将会话附加到当前线程
public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
    if(entity instanceof SomeEntity) {
        Session session = sessionFactory.getCurrentSession();

请参阅getCurrentSession()文档

如果没有,你应该创建一个本地Hibernate拦截器(附加到打开的Session)而不是全局拦截器(附加到SessionFactory),然后设置其会话

AuditableInterceptor interceptor = new AuditableInterceptor()
Session session = sessionFactory.openSession(interceptor);

/**
  * do it before processing anything if you use local interceptor
  */ 
interceptor.setSession(session);

关于触发器,它取决于其他问题,如数据库管理(您拥有数据库管理访问权限。如果没有,请与DBA交谈是最好的选择)。