2016-10-30 3 views
0

Я пытался сделать свой собственный customDetailsService и когда я попытался вызвать сервер для маркера с использованием HTTP:Hibernate, oauth2 не удалось получить транзакций синхронизируются

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 добавляется в конфигурацию спящего режима, и необходимые классы аннотируются с @Transaction.

MyUserDetailsService

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

Как заставить его работать? Каковы мои ошибки?

ответ

1

Вы используете getSession(). GetCurrentSession() ....... если вы поставите getSession(). OpenSession() ..... Она будет работы.

подробнее enter this discussion

0

Ваш @Transactional метод loadUserByUsername() call @Transactional метод findByLogin(), который является конфликтом, не может открыть 2 транзакции.

Идея для вас:

Удалить все @Transactional выше класса и добавить @Transactional на методы, которые вы хотите быть транзакционными. Ваш метод loadUserByUsername() должен быть транзакционным, но ваш метод findByLogin() не может быть транзакционным, потому что он вызывается из транзакционного метода.

+0

К сожалению, это не ключ. Я удалил @Transactional из метода loadUserByUsername(), а затем из метода findByLogin() вместо этого, но все еще существует та же ошибка. – sebaaastian

+0

Вам нужно удалить '@Transactional' над классом, аннотация @Transactional должна быть выше метода. Идея для вас: – paun90

+0

Не работает тоже .. Вероятно, это случай серьезности. – sebaaastian