Spring + Hibernate:没有Hibernate Session绑定到线程 [英] Spring + Hibernate: No Hibernate Session bound to thread
问题描述
我试图实现以下内容:在SpringSecurity注销处理程序中清除数据库中的一些细节。尝试从DB获取用户详细信息后出现此错误的主要问题。其他代码甚至相同的方法在其他情况下都可以正常工作。
public class CurrentUserLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler {
的可能值是
/ **
*
* /
@Autowired
private RequestsService requestsService;
/ **
*
* /
@Autowired
私人OffersService offersService;
/ **
*
* /
@Autowired
private UsersService usersService;
$ b $ **
@Override
public void onLogoutSuccess(HttpServletRequest请求,HttpServletResponse响应,身份验证身份验证)
throws IOException,ServletException {
if(authentication!= null){
UserDetailsExtended details =(UserDetailsExtended)authentication.getPrincipal();
User user = usersService.get(details.getId()); //在这里失败
requestsService.unlockAllByBackoffice(user);
offersService.unlockAllByBackoffice(user);
}
setDefaultTargetUrl(/);
super.onLogoutSuccess(request,response,authentication);
$ / code $ / pre
$ p
< bean id =sessionFactoryclass =org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean>
< property name =dataSourceref =dataSource/>
< property name =packagesToScanvalue =com.ejl.butler.object.data/>
< property name =hibernateProperties>
<道具>
< 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>
< /道具>
< / property>
< / bean>
< bean id =transactionManagerclass =org.springframework.orm.hibernate3.HibernateTransactionManager>
< property name =sessionFactoryref =sessionFactory/>
< / bean>
DAO:
public User get(final Long id){
Session session = SessionFactoryUtils.getSession(sessionFactory,false);
return(User)session.get(User.class,id);
Spring安全配置:
< logout invalidate-session =truelogout-url =/ logoutsuccess-handler-ref =logoutSuccessHandler/>
例外:
没有Hibernate Session绑定到线程,并且配置不允许在这里创建非事务性的$ b $ org.springframework.orm.hibernate3.SessionFactoryUtils.doGetSession(SessionFactoryUtils.java:356)
在org.springframework.orm.hibernate3.SessionFactoryUtils.getSession(SessionFactoryUtils.java:202)
@Transactional
解决了这个问题,但我不明白为什么?我的意思是它只会在所有其他调用中的这个处理函数中失败,没有这个注解,这个方法就可以正常工作!
UPD:
我的临时解决方案是将@Transactional
添加到整个onLogoutSuccess
方法中。 。它的工作原理)解决方案如果您在您的定义中有一个
TransactionManager
spring上下文中,你必须指定@Transactional
堆栈中的某处。否则,您会遇到您遇到的异常,因为您尝试在事务外部运行查询。
对此类指定有一些解决方法
current_session_context_class 在您的hibernate配置中
thread
或< property name =current_session_context_class> org.hibernate.context.ThreadLocalSessionContext< / property>
但它不是生产安全的。
current_session_context_class jta
,thread
和托管
。除此之外,休眠框支持jta
和thread
。在大多数独立的hibernate应用程序或基于Spring轻量级框架和jta
的应用程序中使用thread Java EE环境。
另请尝试
sessionFactory.getCurrentSession()
,而不是SessionFactoryUtils.getSession ()
。I am trying to implement the following: clear some details from DB on SpringSecurity logout handler. 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:
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? 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 wholeonLogoutSuccess
method.. It works)解决方案If you have defined a
TransactionManager
in your spring context you have to specify@Transactional
somewhere in the stack. 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 tothread
or<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
arejta
,thread
andmanaged
. Further to that,jta
andthread
are supported by hibernate out of box.thread
context is used in most stand alone hibernate apps or those based on light weight frameworks like Spring andjta
is used in Java EE environments.Also try
sessionFactory.getCurrentSession()
instead ofSessionFactoryUtils.getSession()
.这篇关于Spring + Hibernate:没有Hibernate Session绑定到线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!