Hibernate无法为远程服务器上的当前线程获取事务同步的Session

zun*_*uno 8 postgresql spring hibernate spring-mvc transactional

我在类似问题上阅读了其他答案,但我找不到解决问题的方法.我有一个Tomcat7服务器和一个Spring应用程序,它使用Hibernate连接到我的PostgreSQL远程数据库.我的框架版本是:Spring框架4.2.2 Spring安全3.2.5 Hibernate 4.3.6

当我在localhost上运行我的应用程序时一切都很好,但是当我在服务器上部署它时,我在登录时收到此错误:

org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
    org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:134)
    org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1014)
    org.myapp.spring.dao.generic.GenericDAOImpl.getSession(GenericDAOImpl.java:59)
    org.myapp.spring.dao.impl.DeveloperDaoImpl.findByUsername(DeveloperDaoImpl.java:51)
    org.myapp.spring.service.impl.DeveloperServiceImpl.findByUsername(DeveloperServiceImpl.java:149)
    org.myapp.spring.web.security.UserDetailsServiceImpl.loadUserByUsername(UserDetailsServiceImpl.java:23)
    org.myapp.spring.web.security.MyAuthenticationProvider.authenticate(MyAuthenticationProvider.java:30)
    org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:167)
    org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:192)
    org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication(UsernamePasswordAuthenticationFilter.java:93)
    org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:217)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:120)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:91)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:53)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:213)
    org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:176)
    org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
    org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
Run Code Online (Sandbox Code Playgroud)

我有两个inizializer文件:

public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        Class[] config = {AppConfig.class};
        return config;
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        Class[] config = {SecurityConfig.class, HibernateConfig.class};
        return config;
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }
Run Code Online (Sandbox Code Playgroud)

@Component
public class SecurityWebApplicationInizializer extends AbstractSecurityWebApplicationInitializer {
}
Run Code Online (Sandbox Code Playgroud)

和三个配置文件:

@EnableWebMvc
@ComponentScan({ "org.myapp.spring.*" })
@EnableTransactionManagement
@PropertySource(value="classpath:myapp.properties")
public class AppConfig extends WebMvcConfigurerAdapter implements ApplicationContextAware {

    @Autowired
    private TokenInterceptor tokenInterceptor;
    private ApplicationContext applicationContext;
    private static final String UTF8 = "UTF-8";

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(tokenInterceptor);
    }

//other methods
}
Run Code Online (Sandbox Code Playgroud)

@Configuration
@EnableWebSecurity
@EnableTransactionManagement
@ComponentScan("org.myapp.spring.web.security")
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired private MyAuthenticationProvider authProvider;
@Autowired private UserDetailsService userDetailsService;

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    auth.authenticationProvider(authProvider);
    auth.userDetailsService(userDetailsService);
}

@Override
public void configure(WebSecurity web) throws Exception {
    DefaultWebSecurityExpressionHandler handler = new DefaultWebSecurityExpressionHandler();
    handler.setPermissionEvaluator(permissionEvaluator());
    web.expressionHandler(handler);
}

@Bean
public PermissionEvaluator permissionEvaluator() {
    return new MyPermissionEvaluator();
}

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.csrf().and()
    .formLogin().loginPage("/html/login").defaultSuccessUrl("/html/index", true).permitAll()
    .and()
    .logout().logoutUrl("/html/logout").logoutSuccessUrl("/html/login?logout").invalidateHttpSession(true).clearAuthentication(true).permitAll()
    .and()
    .authorizeRequests()
    .antMatchers("/html/forbidden").permitAll()
    .antMatchers("/html/logistic").permitAll()
    .antMatchers("/html/ajax/logistic").permitAll()
    .antMatchers("/html/res/**").permitAll()
    .antMatchers("/html").authenticated()
    .antMatchers("/html/**").authenticated()
    .and()
    .exceptionHandling().accessDeniedPage("/html/forbidden");
}
Run Code Online (Sandbox Code Playgroud)

}

最后:

@Configuration
@EnableTransactionManagement
@ComponentScan({ "org.myapp.spring.configuration" })
@PropertySource(value = { "classpath:hibernate.properties" })
public class HibernateConfig {

@Autowired
private Environment environment;

@Bean
public LocalSessionFactoryBean sessionFactory() {
    LocalSessionFactoryBean  sessionFactory = new LocalSessionFactoryBean();
    sessionFactory.setDataSource(dataSource());
    sessionFactory.setPackagesToScan(new String[] { "org.myapp.spring.model"});
    sessionFactory.setHibernateProperties(hibernateProperties());

    try {
        sessionFactory.afterPropertiesSet();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return sessionFactory;
}

@Bean
public DataSource dataSource() {
    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setDriverClassName(environment.getRequiredProperty("hibernate.connection.driver_class"));
    dataSource.setUrl(environment.getRequiredProperty("hibernate.connection.url"));
    dataSource.setUsername(environment.getRequiredProperty("hibernate.connection.username"));
    dataSource.setPassword(environment.getRequiredProperty("hibernate.connection.password"));
    return dataSource;
}

private Properties hibernateProperties() {
    Properties properties = new Properties();
    properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
    properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));
    properties.put("hibernate.format_sql", environment.getRequiredProperty("hibernate.format_sql"));
    return properties;
}

@Bean
@Autowired
public HibernateTransactionManager transactionManager(SessionFactory s) {
    HibernateTransactionManager txManager = new HibernateTransactionManager();
    txManager.setSessionFactory(s);
    return txManager;
}
}
Run Code Online (Sandbox Code Playgroud)

GenericDaoImpl是:

@Repository
public abstract class GenericDAOImpl<T> implements DAO<T> {

    @Autowired
    private SessionFactory sessionFactory;

protected Session getSession() {
            return sessionFactory.getCurrentSession();
        }
Run Code Online (Sandbox Code Playgroud)

每个DAO都扩展了这个类,并有自己的@Repository注释.

每个服务都注释为@transactional.这是UserDetailsS​​ervice的实现:

@Service
@Transactional
public class UserDetailsServiceImpl implements UserDetailsService, MyUserDetailsService {

    @Autowired private DeveloperService devService;
    @Autowired private AuthorizationService authorizationService;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        if(username == null) {
            throw new UsernameNotFoundException("User not found");
        }
        Developer dev = devService.findByUsername(username);

        if(dev == null) {
            throw new UsernameNotFoundException("User not found");
        }
        MyUserDetails user = new MyUserDetails();
        user.setUsername(dev.getUsername());
        user.setPassword(dev.getPassword());
        user.setMaxAuthorityByIndex(dev.getRole());
        return user;
    }
Run Code Online (Sandbox Code Playgroud)

我真的不知道这可能是什么.服务器上的配置可能错误?对我而言似乎是正确的......

ali*_*ani 0

将其添加到您的

    private Properties hibernateProperties() {
        Properties properties = new Properties();
        properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
        properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));
        properties.put("hibernate.format_sql", environment.getRequiredProperty("hibernate.format_sql"));
        properties.put("current_session_context_class","org.springframework.orm.hibernate4.SpringSessionContext");
        return properties;
    }
Run Code Online (Sandbox Code Playgroud)