2010-09-20 53 views
5

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

  • 触发器在各自的表是一个想法,但他们不容易维护?也许他们也不应该成为事务的一部分(如果触发器失败,那么它就可以,但实体更新事务不应该失败)。
  • 为此,使用AoP是一个横切关注点,但必须非常细化,因为只有在实体更改时才捕获值。 (所有编辑没有相应的不同方法......很多编辑发生在单个Java方法中)。
  • 使用Hibernate Event Listeners。

有没有其他方法可以做这种活动?

回答

3

因为你说

所有编辑不具有其相应的不同的方法...... 许多编辑在一个单一的Java方法发生

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

Hibernate文档本身说:

Hibernate的拦截器允许应用程序检查和/或它被保存,更新,删除或是加载之前操纵持久化对象的属性。 一个可能的用途是跟踪审计信息。

但它也说

确保你没有保存sessionspecific状态,因为如果你使用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拦截器(连接在打开的会话),而不是一个全球性的拦截器(连接到SessionFactory的),然后,建立了会议

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

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

有关触发器,它依赖于像数据库管理等问题(你有DB管理权限。如果没有,请与DBA是您最好的选择)。

+0

感谢您的信息亚瑟。对于简单的实现,我试图扩展Hibernate Event Listener。 – 2010-09-20 10:29:46

+0

+1,用于通用解释。 – Bozho 2010-09-20 14:43:38

+0

+1 as bozho said – 2010-09-23 01:58:04

4

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

+0

有意思(+1)你成功使用它了吗? – 2010-09-20 14:13:15

+0

@Arhtur - 不,唉。但我知道使用它的人说它很好:) – Bozho 2010-09-20 14:16:02

+0

和+1也是。 Envers在这里似乎很适合。 – 2010-09-23 01:58:31

相关问题