java - Hibernate拦截器线程安全

标签 java multithreading spring hibernate postgresql

我正在使用 hibernate 拦截器来拦截查询并在将查询发送到 postgresql 数据库之前对其进行更改。

对查询所做的更改特定于每个连接的用户(拦截器正在从他的 session 中获取用户的信息)。

问题是,由于我将 spring 与 hibernate 一起使用,拦截器是单例并在 sessionFactory 级别创建,因此它不是线程安全的。

这是与hibernate相关的spring的配置:

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />

        <property name="configLocation" value="classpath:hibernate.cfg.xml"/>


          <property name="entityInterceptor">
        <ref bean="myEntityInterceptor"/>
    </property>

<property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">${jdbc.dialect}</prop>
                <prop key="hibernate.show_sql">true</prop> 

</props>
</property>
</bean> 


  <bean id="myEntityInterceptor" class="dao.generic.HibernateInterceptor"/>

拦截器类:

@Component
public class HibernateInterceptor extends EmptyInterceptor {

    private static final long serialVersionUID = 1L;

    final static Logger logger = Logger.getLogger(HibernateInterceptor.class);

    @Override
    public String onPrepareStatement(String sql) {
        String ps = super.onPrepareStatement(sql);

        if (SecurityContextHolder.getContext().getAuthentication() != null) {
            UserDetails ud = (UserDetails) SecurityContextHolder
                    .getContext().getAuthentication().getDetails();
                ps = ps.replaceAll("dynamic.", ud.getDb() + ".");
            }
        return ps;
    }

}

所以我正在寻找一种方法来使这个拦截器线程安全,方法是为每个客户端 session 附加一个单独的实例,而不是只为所有用户使用一个实例。

任何帮助将不胜感激..

最佳答案

首先,你的代码对我来说似乎是线程安全的,所以我不确定你是否真的需要这个,但如果你需要,你可以通过创建它来将拦截器设置为每个 session 的一个实例而不是共享实例在 HibernateTransactionManager 的 session 级别通过设置属性 entityInterceptorBeanName

来自 Spring 文档(HibernateTransactionManager.setEntityInterceptorBeanName):

Typically used for prototype interceptors, i.e. a new interceptor instance per session.

所以,确保你的拦截器 bean 的范围是原型(prototype)

看看这个post

关于java - Hibernate拦截器线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32466668/

相关文章:

java - Android WebView 应用程序在旋转时重置

java - Word Wrapping 在 JTextArea 中不起作用

JAVA StdDateSerializer 解析日期

c++ - 在非 boost 线程中使用 boost::thread_specific_ptr

Java 守护进程 - 处理关闭请求

java - Spring Data JPA 无法返回复杂表达式的正确结果

java - SQLGrammarException : could not prepare statement]

java - 如何向MongoDb中的子数据插入数据?

java - 为什么我的并发调用给出 NullPointerException

java - spring @Preauthorize 中的自定义方法