【问题标题】:How to use single sessionFactory for hibernate Intercepter如何将单个 sessionFactory 用于休眠拦截器
【发布时间】:2014-03-16 16:07:56
【问题描述】:

我将 Hibernate Interceptor 与 (hibernate 4.x) 一起使用。我想对 Session 的保存方法进行一些操作。所以我扩展了 EmptyInterceptor。

它有以下几种方法:

onSave() //when save operation is preformed.
postFlush() //called after committed into database 

问题:在 postFlush() 中我想执行 SAVE 操作。所以我的控制陷入了循环。因为当我调用 session.save() 时,会调用 EmptyInterceptor 的 onSave() 和 postFlush() 方法来拦截 SAVE 操作。

为了解决这个问题,我使用了两个会话工厂。 1 用于执行会话操作(保存、更新等),2 用于 HibernateIntercepter。

但我担心如何用单个 sessionFactory 解决这个问题??

公共类 AudiLogInterceptor 扩展 EmptyInterceptor {

public boolean onSave(Object entity, Serializable id, Object[] state,
        String[] propertyNames, Type[] types) {
    return false;
}

// called after committed into database
public void postFlush(Iterator iterator) {
    // want to perform SAVE operation here with Session.save()
    // But whenever I open new seesion here. It falls in loop
    Session tempSession = HibernateUtil.hibernateTemplateLog
            .getSessionFactory().openSession();

    try {
        Item item = new Item();
        item.setName("anyItem");
        item.setValue("anyValue");
        tempSession.save(item);
        tempSession.flush();
    } finally {
        tempSession.close();
    }
    }
} 

【问题讨论】:

    标签: java hibernate spring-mvc interceptor


    【解决方案1】:

    您不使用拦截器来保存对象。您使用它来修改/格式化项目,并让会话对象为您完成其余的工作,但不添加新项目。

    如果您真的想在 flush() 或 commit() 的末尾添加一行,那么您可以使用 Spring-AOP 作为一种选择。在那里,您可以将建议添加到休眠服务,因此,您可以在运行方法后立即保存某些内容。

    解决方法我认为是以下内容。

    public void postFlush(Iterator iterator) {
    
    
    for(; iterator.hasNext();) {
       if(!(iterator.next() instanceof Item)){ //<<<<< You verify if you are saving Item or //other objects, if saving Item, skip this block.
    
       Session tempSession = HibernateUtil.hibernateTemplateLog
                .getSessionFactory().openSession();
    
        try {
            Item item = new Item();
            item.setName("anyItem");
            item.setValue("anyValue");
            tempSession.save(item);
            tempSession.flush();
        } finally {
            tempSession.close();
        }
    }
    }
        }
    } 
    

    【讨论】:

    • 实际上我正在使用休眠拦截器进行审计日志记录。意味着只要有任何 SAVE 或 UPDATE 操作,我的拦截器就会劫持该方法并在审计日志表中插入一条新记录(有关实体的信息。它之前的实际情况和当前情况)。这是参考代码。 mkyong.com/hibernate/hibernate-interceptor-example-audit-log
    • 在您提到的示例链接中,作者将拦截器绑定到特定会话,因此,如果他确实保存或更新,他不会有循环问题。您是否将其绑定到会话?还是您将拦截器应用于整个应用程序?如果你申请了会话,那么请看一下我提到的解决方法,识别在后刷新中的对象,如果是 AuditLog 对象,则跳过审计保存块,因此,后续保存将不被调用,避免程序进入循环。
    • 你能告诉我如何将拦截器绑定到会话吗?我无法在 sessionfactory 上找到将 Connection 作为参数的方法
    • 在示例中参见第 7 步。示例:mkyong.com/hibernate/hibernate-interceptor-example-audit-log。另外,您为什么要寻找连接参数?
    • 我仍然无法实现。问题依然存在。但是我只是添加了解决方法并使用了两个会话工厂:一个用于我的休眠操作,另一个用于审计日志操作(我在其中传递了拦截器类引用)。但我知道这不是一个好的选择,我真的想只使用一个会话工厂,并希望将我的拦截器与单个会话绑定。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-25
    • 1970-01-01
    • 2014-02-02
    相关资源
    最近更新 更多