[英]Spring + Hibernate: No Hibernate Session bound to thread
I am trying to implement the following: clear some details from DB on SpringSecurity logout handler. 我正在尝试实现以下内容:从SpringSecurity注销处理程序上的数据库中清除一些详细信息。 The main problem that after trying to get user details from DB I get this error. 尝试从数据库获取用户详细信息后出现的主要问题是此错误。 The rest of code and even the same method work fine in other cases. 其余的代码,甚至相同的方法在其他情况下也可以正常工作。
public class CurrentUserLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler {
/**
*
*/
@Autowired
private RequestsService requestsService;
/**
*
*/
@Autowired
private OffersService offersService;
/**
*
*/
@Autowired
private UsersService usersService;
/**
*
*/
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException, ServletException {
if (authentication != null) {
UserDetailsExtended details = (UserDetailsExtended) authentication.getPrincipal();
User user = usersService.get(details.getId()); // fails here
requestsService.unlockAllByBackoffice(user);
offersService.unlockAllByBackoffice(user);
}
setDefaultTargetUrl("/");
super.onLogoutSuccess(request, response, authentication);
}
}
Config: 配置:
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.ejl.butler.object.data" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
<prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</prop>
<prop key="hibernate.cache.region.factory_class">${hibernate.cache.region.factory_class}</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
DAO: DAO:
public User get(final Long id) {
Session session = SessionFactoryUtils.getSession(sessionFactory, false);
return (User) session.get(User.class, id);
}
Spring security config: 春季安全配置:
<logout invalidate-session="true" logout-url="/logout" success-handler-ref="logoutSuccessHandler"/>
Exception: 例外:
No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
at org.springframework.orm.hibernate3.SessionFactoryUtils.doGetSession(SessionFactoryUtils.java:356)
at org.springframework.orm.hibernate3.SessionFactoryUtils.getSession(SessionFactoryUtils.java:202)
@Transactional
resolves the problem but I can't understand why? @Transactional
解决了问题,但我不明白为什么? I mean it fails only in this handler in all other calls this method works fine without this annotation! 我的意思是,它只会在此处理程序的所有其他调用中失败,如果没有此注释,此方法将正常工作!
Thank you in advance! 先感谢您!
UPD: My temporary solution is to add @Transactional
to whole onLogoutSuccess
method.. It works) UPD:我的临时解决方案是将@Transactional
添加到整个onLogoutSuccess
方法中。
If you have defined a TransactionManager
in your spring context you have to specify @Transactional
somewhere in the stack. 如果您在Spring上下文中定义了TransactionManager
,则必须在堆栈中的某处指定@Transactional
。 Otherwise you will get the exception you encountered because you are trying to run a query outside of a transaction. 否则,您将遇到遇到的异常,因为您试图在事务外部运行查询。
There are workarounds to this such specifying current_session_context_class
in your hibernate configuration to thread
or 有一些解决方法,例如在休眠配置中将current_session_context_class
指定为thread
或
<property name="current_session_context_class">org.hibernate.context.ThreadLocalSessionContext</property>
but it's not production safe. 但这并不安全。 . 。
The possible values for current_session_context_class
are jta
, thread
and managed
. current_session_context_class
的可能值为jta
, thread
和managed
。 Further to that, jta
and thread
are supported by hibernate out of box. 除此之外,休眠状态还支持jta
和thread
。 thread
context is used in most stand alone hibernate apps or those based on light weight frameworks like Spring and jta
is used in Java EE environments. thread
上下文用于大多数独立的休眠应用程序中,或者基于轻量级框架(如Spring)的应用程序,而jta
用于Java EE环境。
Also try sessionFactory.getCurrentSession()
instead of SessionFactoryUtils.getSession()
. 还可以尝试使用sessionFactory.getCurrentSession()
而不是SessionFactoryUtils.getSession()
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.