如何在 Hibernate 中覆盖 Session.save()?

Posted

技术标签:

【中文标题】如何在 Hibernate 中覆盖 Session.save()?【英文标题】:How to Override Session.save() in Hibernate? 【发布时间】:2019-11-03 05:05:41 【问题描述】:

我想注入所有 session.save() 如下所示。

public class MyHbnSession implements Session 

       @Override
       public Serializable save(Object obj) throws HibernateException 
           if(obj instanceof MyClass) 
               MyClass mc = (MyClass) obj;
               mc.setVal("Injected Prop");
           
           return super.save(obj);
       

然后每当我 getSession 我应该收到我的自定义会话对象

MyHbnSession session = HibernateUtil.getSessionFactory().openSession();

我找不到使用休眠的方法。还有两件我想念的主要事情

org.hibernate.Session 是一个接口,而 org.hibernate.impl.SessionImpl 是实际的实现。但是在this case 中实现了会话 如何告诉 hibernate 这是我们的自定义会话实现,应该由会话工厂使用

请让我了解一下我所缺少的东西。感谢您的帮助。

PS : 我可以用 aspectj 做到这一点,但由于很多原因不想这样做。

【问题讨论】:

您的应用程序中是否使用了某种 CDI? @Nico 抱歉,CDI 是什么意思? 某种依赖注入框架。抱歉,C 是错误的且具有误导性,它只是 DI。 【参考方案1】:

在@pdem 回答提示和this post 的帮助下,我能够解决问题。这是我所做的要点。

拦截器实现

import java.io.Serializable;

import org.hibernate.EmptyInterceptor;
import org.hibernate.type.Type;

public class MyHbnInterceptor extends EmptyInterceptor 

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    @Override
    public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) 
        if(entity instanceof MyClass) 
            // TODO: Do your operations here
        
        return super.onSave(entity, id, state, propertyNames, types);
    

让hibernate知道我们的拦截器可以通过两种方式完成

会话范围 - 仅适用于创建的会话
Session session = sf.openSession( new MyHbnInterceptor() );
会话工厂范围 - 适用于会话工厂创建的所有会话
new Configuration().setInterceptor( new MyHbnInterceptor() );

在this link了解更多。

干杯!

【讨论】:

【参考方案2】:

我个人不会覆盖会话,而是使用 JPA 注释 @PreUpdate 和 @PrePersist。

这种方式你可以直接修改所需的对象,如果你需要很多类的话,可能还有包含“val”的抽象类。

这样您就不必使用“instanceof”并使实体的代码更具可读性。

【讨论】:

感谢 @pdem 的提示,但这些 JPA 注释不适用于休眠。 @Vivek,从休眠切换到 JPA 的工作并不多,使用 entityManager 而不是会话。有 Hibernate-JPA 注释来保持 Hibernate 特定的功能。

以上是关于如何在 Hibernate 中覆盖 Session.save()?的主要内容,如果未能解决你的问题,请参考以下文章

如何理解Hibernate中的HibernateSessionFactory类

在ssh框架中的dao类中如何获取hibernate中的session

hibernate中 session.save(实体类)方法的原理

如何将 Hibernate Session 绑定到 Grails 中的线程?

Spring Boot:在单元测试中使用 Hibernate Session

如何使用 JDBC 在 spring-session 中初始化模式