简体   繁体   English

Hibernate拦截器线程安全

[英]Hibernate interceptor thread safety

I'm using a hibernate interceptor to intercept queries and alter them before they are sent to the postgresql database. 我正在使用休眠拦截器来拦截查询,并在将查询发送到Postgresql数据库之前对其进行更改。

The change made on the queries is specific to every connected user(the interceptor is getting the user's information from his session). 对查询所做的更改特定于每个连接的用户(拦截器正在从其会话中获取用户的信息)。

The problem is, since i'm using spring along with hibernate, the interceptor is a singleton and made at the sessionFactory level, so it's not thread-safe. 问题是,由于我将Spring和Hibernate一起使用,所以拦截器是单例的,是在sessionFactory级别上制成的,因此它不是线程安全的。

This is the configuration of spring related to 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"/>

And the interceptor class : 和拦截器类:

@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;
    }

}

So I'm lookinf for a way to make this interceptor thread-safe by attaching a seperate instance for every client session and not only one instance used by all the users. 因此,我正在寻找一种方法,通过为每个客户端会话附加一个单独的实例,而不是为所有用户使用一个实例,来使此拦截器线程安全。

Any help will be appreciated.. 任何帮助将不胜感激..

First, your code seems thread safe to me, so I'm not sure if you really need this, but in case you do, you can set the interceptor to be an instance per session instead of a shared instance by creating it at Session level on HibernateTransactionManager by setting the property entityInterceptorBeanName 首先,您的代码对我来说似乎是线程安全的,因此我不确定您是否确实需要这样做,但是如果您确实需要,可以在会话级别创建拦截器,使其设置为每个会话的实例,而不是共享实例通过设置属性entityInterceptorBeanNameHibernateTransactionManager

From Spring Doc ( HibernateTransactionManager.setEntityInterceptorBeanName ): 从Spring Doc( HibernateTransactionManager.setEntityInterceptorBeanName ):

Typically used for prototype interceptors, ie a new interceptor instance per session. 通常用于原型拦截器,即每个会话一个新的拦截器实例。

So, make sure your interceptor bean is scoped as prototype 因此,请确保您的拦截器bean的作用域是原型

Take a look at this post 看看这篇文章

SingleTon objects can be treated as thread safe, as long as the object does not hold any state information (ie, instance variables with getters and setters). 只要对象不包含任何状态信息(即具有getter和setter的实例变量),SingleTon对象就可以视为线程安全的。 So, here in this example, HibernateInterceptor object is thread safe. 因此,在此示例中,HibernateInterceptor对象是线程安全的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM