我自己对此进行了很多调查,并想与大家分享我的经验(底部包含有用的链接)。
拦截器
要使用拦截器,您需要扩展org.hibernate.EmptyInterceptor
类并覆盖您想要拦截的方法。
在您的情况下,您可能需要使用onSave(...)
方法。
package foo.bar;
import org.hibernate.EmptyInterceptor;
import org.hibernate.type.Type;
import java.io.Serializable;
public class MyInterceptor extends EmptyInterceptor {
@Override
public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
return false;
}
}
您需要在Spring/Hibernate中注册您的拦截器。 您可以在您的application.properties或application.yml中完成此操作。
spring:
jpa:
properties:
hibernate.ejb.interceptor: foo.bar.MyInterceptor
使用拦截器的优点是它(可能)需要的代码较少,并且配置相对简单。
缺点是你只能在整个应用程序中使用一个拦截器,而且与API一起使用可能会令人困惑。
事件监听器
对于事件,您可以实现Hibernate的org.hibernate.event.spi.*Listener
接口之一。
在您的情况下,您可能需要org.hibernate.event.spi.PreInsertEventListener
。
您必须在EventListenerRegistry
中注册您的事件。
为此,您可以将您的类作为@Component
,将EntityManagerFactory
自动装配到您的类中,并创建一个@PostConstruct
方法来注册您的类。
package foo.bar;
import org.hibernate.event.service.spi.EventListenerRegistry;
import org.hibernate.event.spi.EventType;
import org.hibernate.event.spi.PreInsertEvent;
import org.hibernate.event.spi.PreInsertEventListener;
import org.hibernate.internal.SessionFactoryImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.persistence.EntityManagerFactory;
@Component
public class MyEventListener implements PreInsertEventListener {
@Autowired
private EntityManagerFactory entityManagerFactory;
@PostConstruct
private void init() {
SessionFactoryImpl sessionFactory = entityManagerFactory.unwrap(SessionFactoryImpl.class);
EventListenerRegistry registry = sessionFactory.getServiceRegistry().getService(EventListenerRegistry.class);
registry.getEventListenerGroup(EventType.PRE_INSERT).appendListener(this);
}
@Override
public boolean onPreInsert(PreInsertEvent preInsertEvent) {
return false;
}
}
监听器的优点在于你可以有任意多个,API比拦截器更好用,代码和配置都在同一个地方。
缺点是配置较长且复杂。