【问题标题】:Logging Entity changes in Java Web Application在 Java Web 应用程序中记录实体更改
【发布时间】:2010-10-05 18:46:42
【问题描述】:

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

  • 各自表上的触发器是一种想法,但它们不容易维护?也许它们也不应该是事务的一部分(如果触发器失败,它可以,但实体更新事务不应该失败)。
  • 为此使用 AoP,因为它是一个横切关注点,但必须非常精细,例如仅在实体更改时捕获值。 (所有编辑都没有相应的不同方法……许多编辑发生在一个 java 方法中)。
  • 使用休眠事件监听器。

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

【问题讨论】:

    标签: hibernate spring aop


    【解决方案1】:

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

    【讨论】:

    • 有趣(+1)你用成功了吗??
    • @Arhtur - 不,唉。但我知道有人使用它并说它很好:)
    • 还有 +1。 Envers 似乎很适合这里。
    【解决方案2】:

    因为你说

    所有编辑都没有对应的不同方法...许多编辑发生在一个 java 方法中

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

    Hibernate 文档本身说:

    Hibernate Interceptor 允许应用程序在保存、更新、删除或加载持久对象之前检查和/或操作它的属性。 一种可能的用途是跟踪审计信息。

    但它也说

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

    如果你使用 Spring 管理的 Transaction,你可以使用 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 交谈)。

    【讨论】:

    • 感谢亚瑟提供的信息。对于简单的实现,我正在尝试扩展 Hibernate Event Listener。
    猜你喜欢
    • 1970-01-01
    • 2010-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-16
    • 2013-08-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多