[英]Hibernate interceptor thread safety
我正在使用休眠拦截器来拦截查询,并在将查询发送到Postgresql数据库之前对其进行更改。
对查询所做的更改特定于每个连接的用户(拦截器正在从其会话中获取用户的信息)。
问题是,由于我将Spring和Hibernate一起使用,所以拦截器是单例的,是在sessionFactory级别上制成的,因此它不是线程安全的。
这是与休眠有关的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;
}
}
因此,我正在寻找一种方法,通过为每个客户端会话附加一个单独的实例,而不是为所有用户使用一个实例,来使此拦截器线程安全。
任何帮助将不胜感激..
首先,您的代码对我来说似乎是线程安全的,因此我不确定您是否确实需要这样做,但是如果您确实需要,可以在会话级别创建拦截器,使其设置为每个会话的实例,而不是共享实例通过设置属性entityInterceptorBeanName
在HibernateTransactionManager
从Spring Doc( HibernateTransactionManager.setEntityInterceptorBeanName
):
通常用于原型拦截器,即每个会话一个新的拦截器实例。
因此,请确保您的拦截器bean的作用域是原型
看看这篇文章
只要对象不包含任何状态信息(即具有getter和setter的实例变量),SingleTon对象就可以视为线程安全的。 因此,在此示例中,HibernateInterceptor对象是线程安全的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.