[英]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.