gpt4 book ai didi

hibernate - 如何在创建时拦截所有 Hibernate session (Spring/Grails 环境)

转载 作者:行者123 更新时间:2023-12-04 22:37:28 26 4
gpt4 key购买 nike

有没有办法在创建所有新的 Hibernate session 时拦截它们?我需要访问每个 Session 实例以启用带有参数的 Hibernate 过滤器。

我使用的唯一解决方案涉及包装 SessionFactory,但这涉及到很多半讨厌的 hack 以及它需要我实现大约 60 种方法,其中只有少数是有趣的。

Hibernate 的 SessionFactory 实现由于某些烦人的原因被声明为 final,因此扩展它不是一个选项。我也尝试过方面和 Java 代理,但没有任何运气。

最佳答案

我能够创建一个 JDK 代理:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Date;

import org.hibernate.SessionFactory;
import org.hibernate.engine.SessionFactoryImplementor;

public class SessionFactoryProxyCreator {

public static SessionFactory instance;

public static SessionFactory createProxy(final SessionFactory realSessionFactory) {
ClassLoader cl = SessionFactory.class.getClassLoader();
Class<?>[] interfaces = new Class[] { SessionFactory.class, SessionFactoryImplementor.class };
instance = (SessionFactory)Proxy.newProxyInstance(cl, interfaces, new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

if ("openSession".equals(method.getName())) {
System.out.println("NEW SESSION AT " + new Date());
}

return method.invoke(realSessionFactory, args);
}
});

return instance;
}
}

您可以从自定义 SessionFactoryBean 调用它:
import org.codehaus.groovy.grails.orm.hibernate.ConfigurableLocalSessionFactoryBean;
import org.hibernate.HibernateException;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class MyConfigurableLocalSessionFactoryBean extends ConfigurableLocalSessionFactoryBean {

public MyConfigurableLocalSessionFactoryBean() {
setCurrentSessionContextClass(MyCurrentSessionContext.class);
}

@Override
protected SessionFactory buildSessionFactory() throws Exception {
setExposeTransactionAwareSessionFactory(false);
return SessionFactoryProxyCreator.createProxy(super.buildSessionFactory());
}

@Override
protected SessionFactory newSessionFactory(Configuration config) throws HibernateException {
setExposeTransactionAwareSessionFactory(false);
return SessionFactoryProxyCreator.createProxy(super.newSessionFactory(config));
}
}

这取决于 Spring 的 SpringSessionContext 的修改版本,它使用代理而不是真正的 session 工厂:
import org.hibernate.HibernateException;
import org.hibernate.classic.Session;
import org.hibernate.context.CurrentSessionContext;
import org.hibernate.engine.SessionFactoryImplementor;
import org.springframework.orm.hibernate3.SessionFactoryUtils;

public class MyCurrentSessionContext implements CurrentSessionContext {

public MyCurrentSessionContext(SessionFactoryImplementor sessionFactory) {
// ignore the real sessionFactory, need to use the proxy
}

public Session currentSession() throws HibernateException {
try {
return (org.hibernate.classic.Session)SessionFactoryUtils.doGetSession(
SessionFactoryProxyCreator.instance, false);
}
catch (IllegalStateException e) {
throw new HibernateException(e.getMessage());
}
}
}

这需要在 resources.groovy 中注册以替换标准的 Grails ConfigurableLocalSessionFactoryBean:
import org.codehaus.groovy.grails.commons.ApplicationHolder as AH
import org.codehaus.groovy.grails.orm.hibernate.events.PatchedDefaultFlushEventListener

beans = {

sessionFactory(MyConfigurableLocalSessionFactoryBean) {

def ds = AH.application.config.dataSource
def hibConfig = AH.application.config.hibernate

dataSource = ref('dataSource')
List hibConfigLocations = []
if (AH.application.classLoader.getResource('hibernate.cfg.xml')) {
hibConfigLocations << 'classpath:hibernate.cfg.xml'
}
def explicitLocations = hibConfig?.config?.location
if (explicitLocations) {
if (explicitLocations instanceof Collection) {
hibConfigLocations.addAll(explicitLocations.collect { it.toString() })
}
else {
hibConfigLocations << hibConfig.config.location.toString()
}
}
configLocations = hibConfigLocations
if (ds?.configClass) {
configClass = ds.configClass
}
hibernateProperties = ref('hibernateProperties')
grailsApplication = ref('grailsApplication', true)
lobHandler = ref('lobHandlerDetector')
entityInterceptor = ref('entityInterceptor')
eventListeners = ['flush': new PatchedDefaultFlushEventListener(),
'pre-load': ref('eventTriggeringInterceptor'),
'post-load': ref('eventTriggeringInterceptor'),
'save': ref('eventTriggeringInterceptor'),
'save-update': ref('eventTriggeringInterceptor'),
'post-insert': ref('eventTriggeringInterceptor'),
'pre-update': ref('eventTriggeringInterceptor'),
'post-update': ref('eventTriggeringInterceptor'),
'pre-delete': ref('eventTriggeringInterceptor'),
'post-delete': ref('eventTriggeringInterceptor')]
}
}

关于hibernate - 如何在创建时拦截所有 Hibernate session (Spring/Grails 环境),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3577837/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com