更新架构时,当前线程的作用域“会话”无效

时间:2019-01-06 15:32:37

标签: java spring spring-boot spring-mvc

我尝试对应用程序实施动态数据库路由步骤。 当“ hibernate.hbm2ddl.auto”为空时,一切正常。

当我想更新数据库方案时,我将“ hibernate.hbm2ddl.auto”更改为“ update”,并且出现此错误:

  

由以下原因引起:org.springframework.beans.factory.BeanCreationException:创建名称为“ scopedTarget.preferredDatabaseSession”的bean时出错:作用域“会话”在当前线程中不起作用;如果您打算从单例中引用它,请考虑为此bean定义作用域代理。嵌套异常为java.lang.IllegalStateException:未找到线程绑定的请求:您是在实际Web请求之外引用请求属性,还是在原始接收线程之外处理请求?如果您实际上是在Web请求中操作并且仍然收到此消息,则您的代码可能在DispatcherServlet / DispatcherPortlet之外运行:在这种情况下,请使用RequestContextListener或RequestContextFilter公开当前请求。

     

由以下原因引起:java.lang.IllegalStateException:找不到线程绑定的请求:您是在实际Web请求之外引用请求属性,还是在原始接收线程之外处理请求?如果您实际上是在Web请求中操作并且仍然收到此消息,则您的代码可能在DispatcherServlet / DispatcherPortlet之外运行:在这种情况下,请使用RequestContextListener或RequestContextFilter公开当前请求。       在org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:131)〜[spring-web-4.3.9.RELEASE.jar:4.3.9.RELEASE]

我尝试创建自己的RequestContextHolder,但是没有用。我有一个会话范围bean,我想我错过了一些东西。

我的会话范围类:

@Component
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class PreferredDatabaseSession implements Serializable {

private DatabaseEnvironment preferredDb;

public DatabaseEnvironment getPreferredDb() {
    return preferredDb;
}

public void setPreferredDb(DatabaseEnvironment preferredDb) {
    this.preferredDb = preferredDb;
}

}

我这样称呼它:

public class DataSourceRouter extends AbstractRoutingDataSource {

    @Autowired
    private PreferredDatabaseSession db;

    @Override
    protected Object determineCurrentLookupKey() {
    return db.getPreferredDb();
    }
}

也可以从此处致电:

@Service
public class UserDetailsServiceImpl implements UserDetailsService {

@Autowired
private PreferredDatabaseSession userDatabaseSession;

private void setPreferredDatabase() throws DataAccessException {
    // String preferredDb = (String) request.getSession().getAttribute("preferredDb");
    String preferredDb = request.getParameter("preferredDb");
    if (preferredDb.equals(Constants.JPLATFORM)) {
        userDatabaseSession.setPreferredDb(DatabaseEnvironment.JPLATFORM);
    } else if (preferredDb.equals(Constants.TIGER)) {
        userDatabaseSession.setPreferredDb(DatabaseEnvironment.TIGER);
    }
}
}

1 个答案:

答案 0 :(得分:0)

UserDetailsS​​erviceImpl是一个单例bean,而HttpServletRequest是一个请求范围的bean,这就是例外。

尝试使用

ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    HttpServletRequest request = requestAttributes.getRequest();

代替自动装配HttpServletRequest

在路由时也属于默认数据源:

@Override
protected Object determineCurrentLookupKey() {
if (RequestContextHolder.getRequestAttributes() == null) {
    return DEFAULT_ONE;
}
return db.getPreferredDb();
}