Hibernate,oauth2 无法获得事务同步

Hibernate, oauth2 could not obtain transaction-synchronized

我尝试制作自己的 customDetailsS​​ervice,当我尝试使用 http:

调用服务器获取令牌时

POST http://localhost:8080/SpringSecurityOAuth2Example/oauth/token?grant_type=password&username=bill&password=abc123

结果出现异常:

<UnauthorizedException xmlns="">
    <error>unauthorized</error>
    <error_description>Could not obtain transaction-synchronized Session for current thread</error_description>
</UnauthorizedException>

此外,当我调试这个时,我确定方法 userDaoImpl.findByLogin(login) 存在问题。但是当我从我的 restController 中调用它进行测试时,它工作正常并且注释是类似的。

@EnableTransactiomManagement在hibernate配置中添加,需要类注解@Transaction。

我的用户详细信息服务

package com.maxim.spring.restcontroller;

import java.util.ArrayList;
import java.util.List;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;


import com.maxim.spring.dao.UserDao;
import com.maxim.spring.model.User;

@Transactional
@Service("MyUserDetailsService")
public class MyUserDetailsService implements UserDetailsService {

    @Autowired
    @Qualifier("userDaoImpl")
    private UserDao userDaoImpl;



    @Transactional(readOnly=true)
    @Override
    public UserDetails loadUserByUsername(String login) throws UsernameNotFoundException {


        User user = userDaoImpl.findByLogin(login);


        if(user == null) {
            System.out.println("User was not found ");
            throw new UsernameNotFoundException(login);
        } else {
            System.out.println("Tu powinienem byc i jestem");
            new org.springframework.security.core.userdetails.User(user.getLogin(), user.getPass(), getUserRole(user));
        }

        return null;
    }

    public List<GrantedAuthority> getUserRole(User user) {
        List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();

        authorities.add(new SimpleGrantedAuthority("ROLE_"+user.getRole()));

        return authorities;
    }

UserDaoImpl:

package com.maxim.spring.dao;

import java.util.List;


import org.springframework.transaction.annotation.Transactional;

import org.hibernate.Query;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;

import com.maxim.spring.model.User;


@Transactional
@Repository("userDaoImpl")
public class UserDaoImpl extends AbstractDao implements UserDao{

    public User findById(Integer id) {



    @Override
    public User findByLogin(String login) {
        System.out.println("w srodku1");
        Query qr = (Query) getSession().getCurrentSession().createQuery("from User u where u.login=:login").setParameter("login", login);
        System.out.println("w srodku2");
        User u = (User) qr.list().get(0);
        System.out.println("w srodku3");
        return u;
    }





}

休眠配置:

@EnableTransactionManagement
@Configuration
@ComponentScan({ "com.maxim.spring.configuration" })
@PropertySource(value = { "classpath:application.properties" })
public class HibernateConfiguration {

    @Autowired
    private Environment environment;

    @Bean
    public LocalSessionFactoryBean sessionFactory() {
        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
        sessionFactory.setDataSource(dataSource());
        sessionFactory.setPackagesToScan(new String[] { "com.maxim.spring.model", "com.maxim.spring.services" });
        sessionFactory.setHibernateProperties(hibernateProperties());
        return sessionFactory;
     }

    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(environment.getRequiredProperty("jdbc.driverClassName"));
        dataSource.setUrl(environment.getRequiredProperty("jdbc.url"));
        dataSource.setUsername(environment.getRequiredProperty("jdbc.username"));
        dataSource.setPassword(environment.getRequiredProperty("jdbc.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;
    }
}

如何让它发挥作用?我的错误是什么?

您的 @Transactional 方法 loadUserByUsername() 调用 @Transactional 方法 findByLogin() 冲突,无法打开 2 个事务。

给你的想法:

删除上面的所有@Transactional class 并在您希望成为事务性的方法上添加@Transactional。您的方法 loadUserByUsername() 必须是事务性的,但您的方法 findByLogin() 不能是事务性的,因为它是从事务性方法调用的。

您正在使用 getSession().getCurrentSession()...... 如果你输入 getSession().openSession().....它会起作用。

更多信息enter this discussion