Hibernate,oauth2无法获得事务同步

时间:2016-10-30 14:33:15

标签: java spring hibernate oauth2

我尝试创建自己的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注释。

MyUserDetailsS​​ervice

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;
    }
}

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

2 个答案:

答案 0 :(得分:1)

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

更多信息enter this discussion

答案 1 :(得分:0)

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

想法:

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