没有可用的'org.hibernate.SessionFactory'类型的合格Bean:至少应有1个合格为自动装配候选的Bean

时间:2019-05-07 13:08:45

标签: hibernate spring-boot oauth-2.0 sessionfactory hibernate-entitymanager

当前我在控制器和服务层之间的Autowire配置中遇到问题,但是我收到了依赖注入问题。我正在使用JPA开发Spring Boot 2.1.2.RELEASE应用程序。我定义了存储库接口和实施。

UserRepositoryInterface:

set_default_executor

UserSchoolRepositoryInterface:

@Repository
@Transactional
public interface UserRepositoryInterface extends JpaRepository<Account,Long> {
@Query("SELECT a FROM Account a WHERE a.userName = :username")
Account findByLogin(@Param("username") String username);
}

我正在使用Oauth2进行授权。

主要:

@Repository
@Transactional
public interface UserSchoolRepositoryInterface extends JpaRepository<UserSchool, Integer> {

@Query("select s.id " + "from Account u,School s,UserSchool us "
        + "where  u.id=?1 " + "and us.userId = u.id "
        + "and us.schoolId = s.id")
Integer findSchoolByUserId(Long id);
}

OAuth2AuthorizationConfig:

@SpringBootApplication
public class Main extends SpringBootServletInitializer {

public static void main(String[] args) {
    SpringApplication.run(Main.class, args);
}
}

WebSecurityConfiguration:

@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationConfig extends AuthorizationServerConfigurerAdapter {

@Value("${check-user-scopes}")
private Boolean checkUserScopes;

@Autowired
private DataSource dataSource;

@Autowired
private PasswordEncoder passwordEncoder;

@Autowired
private UserDetailsService userDetailsService;

@Autowired
private ClientDetailsService clientDetailsService;

@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;

@Bean
public OAuth2RequestFactory requestFactory() {
    CustomOauth2RequestFactory requestFactory = new CustomOauth2RequestFactory(clientDetailsService);
    requestFactory.setCheckUserScopes(true);
    return requestFactory;
}

@Bean
public TokenStore tokenStore() {
    return new JwtTokenStore(jwtAccessTokenConverter());
}

@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter() {
    JwtAccessTokenConverter converter = new CustomTokenEnhancer();
    converter.setKeyPair(new KeyStoreKeyFactory(new ClassPathResource("keystore.jks"), "password".toCharArray()).getKeyPair("keystore"));
    return converter;
}

@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
    clients.jdbc(dataSource).passwordEncoder(passwordEncoder);
}

@Bean
public TokenEndpointAuthenticationFilter tokenEndpointAuthenticationFilter() {
    return new TokenEndpointAuthenticationFilter(authenticationManager, requestFactory());
}


@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
    oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");
}

@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
    endpoints.tokenStore(tokenStore()).tokenEnhancer(jwtAccessTokenConverter())
            .authenticationManager(authenticationManager).userDetailsService(userDetailsService);
    if (checkUserScopes)
        endpoints.requestFactory(requestFactory());
}
}

CustomUserDetailsS​​ervice:

@Configuration
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

@Autowired
private UserDetailsService userDetailsService;

@Bean
public PasswordEncoder passwordEncoder() {
    return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}

@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
    return super.authenticationManagerBean();
}

@Override
public void configure(HttpSecurity http) throws Exception {
    http.csrf().disable().exceptionHandling()
            .authenticationEntryPoint(
                    (request, response, authException) -> response.sendError(HttpServletResponse.SC_UNAUTHORIZED))
            .and().authorizeRequests().antMatchers("/**").authenticated().and().httpBasic();
}

@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
}

CustomOauth2RequestFactory:

@Service(value = "userDetailsService")
public class CustomUserDetailsService implements UserDetailsService {


@Autowired
private UserRepositoryInterface userRepositoryInterface;
@Autowired
private UserRoleRepositoryInterface userRoleRepositoryInterface;
@Autowired
private UserSchoolRepositoryInterface userSchoolRepositoryInterface;

@Override
public UserDetails loadUserByUsername(String input) {
    Account user = userRepositoryInterface.findByLogin(input);

    if (null == user) {
        throw new UsernameNotFoundException(
                "INVALID USER WITH LOGIN: " + input);
    } else {
        List<String> userRoles = userRoleRepositoryInterface.findRoleByUserId(user.getId());
        Integer userSchool = userSchoolRepositoryInterface.findSchoolByUserId(user.getId());
        return new CustomUserDetails(user, userRoles, userSchool);
    }
}
}

下面是我的剩余控制器类和服务。

LoopController:

public class CustomOauth2RequestFactory extends DefaultOAuth2RequestFactory {

@Autowired
private TokenStore tokenStore;

@Autowired
private UserDetailsService userDetailsService;

public CustomOauth2RequestFactory(ClientDetailsService clientDetailsService) {
    super(clientDetailsService);
}


@Override
public TokenRequest createTokenRequest(Map<String, String> requestParameters,
        ClientDetails authenticatedClient) {
    if (requestParameters.get("grant_type").equals("refresh_token")) {
        OAuth2Authentication authentication = tokenStore.readAuthenticationForRefreshToken(
                tokenStore.readRefreshToken(requestParameters.get("refresh_token")));
        SecurityContextHolder.getContext()
                .setAuthentication(new UsernamePasswordAuthenticationToken(authentication.getName(), null,
                        userDetailsService.loadUserByUsername(authentication.getName()).getAuthorities()));
    }
    return super.createTokenRequest(requestParameters, authenticatedClient);
}
}

LoopDao:

@RestController
@RequestMapping("/users")
public class LoopController {

@Autowired
private AccountService accountService;
@Autowired
public LoopDao loopDao;
public static RestTemplate restTemplate = new RestTemplate();
Gson gson;
GsonBuilder builder;

@RequestMapping(value="/checkCategoryName",method=RequestMethod.POST)
public @ResponseBody String checkCategoryName(@RequestBody String categoryName){
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    Account customUser = accountService.findByUsername(authentication.getPrincipal().toString());
    School school = customUser.getUserSchool().getSchoolId();
    System.out.println("school : "+school.getName());
    String jsonAccts = null;
    long count = loopDao.checkCategoryName(categoryName,school.getId());
    System.out.println("count "+count);
    return (count == 0)? "no" : "yes";


}              
    }

LoopService:

public interface LoopDao {

long checkCategoryName(String categoryName, int id);
}

build.gradle:

@Service
@Transactional
public class LoopService implements LoopDao {

@Autowired
private SessionFactory sessionFactory;

private org.hibernate.Session getCurrentSession(){
    return sessionFactory.getCurrentSession();
}

@Override
public long checkCategoryName(String categoryName, int id) {
    Session session = getCurrentSession();
    try {
        long count = (long) session.createQuery("select count(name) from Category where name = :catName and schoolId = :schoolId")
                .setParameter("catName", categoryName).setParameter("schoolId", id).uniqueResult();
        return count;
    } catch (Exception e) {
        e.printStackTrace();
        return -1;
    }
}

@Override
public int createCategory(Category category) {
    Session session = getCurrentSession();
    Transaction tx = session.beginTransaction();
    try {
        Serializable genid = session.save(category);
        tx.commit();
        return Integer.parseInt(genid.toString());
    } catch (Exception e) {
        e.printStackTrace();
        tx.rollback();
        return -1;
    }
}
}

application.yml:

group 'com.lss.loopserver'
version '1.0-SNAPSHOT'
buildscript {
ext {
    springBootVersion = '2.1.2.RELEASE'
}
repositories {
    mavenCentral()
}
dependencies {
    classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}

apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'war'

war {
baseName = 'LoopServer'
version =  '0.0.1'
}

sourceCompatibility = 1.8

repositories {
jcenter()
maven { url "http://repo.spring.io/libs-snapshot" }
}

dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
compile('org.springframework.boot:spring-boot-starter-actuator')
compile('org.springframework.boot:spring-boot-starter-data-jpa')
compile('org.springframework.boot:spring-boot-starter-security')
compile('org.springframework.cloud:spring-cloud-starter-oauth2')
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.springframework.boot:spring-boot-starter-tomcat')
compile('javax.inject:javax.inject:1')
compile ('mysql:mysql-connector-java:6.0.6')
compile ('com.google.code.gson:gson:2.8.1')
compile group: 'commons-fileupload', name: 'commons-fileupload', version: '1.3.3'
compile 'org.apache.commons:commons-io:1.3.2'
runtime('org.springframework.boot:spring-boot-devtools')
runtime('com.h2database:h2')
testCompile('org.springframework.boot:spring-boot-starter-test')
}

dependencyManagement {
imports {
    mavenBom "org.springframework.cloud:spring-cloud-dependencies:Greenwich.RC2"
}
}

bootRun {
sourceResources sourceSets.main
}

我的应用程序不会以以下消息开头:

security:
  oauth2:
    client:
      clientId: clientapp
      clientSecret: 123456
      authorized-grant-types: authorization_code,refresh_token,password
      scope: openid
    resource.jwt:
      key-pair:
        alias: keystore
        store-password: password
    resource:
      token-info-uri: http://192.168.1.2:8333/LoopServer/oauth/token
      prefer-token-info: true
server:
  port: 8333
  servlet:
    context-path: /LoopServer
spring:
  datasource:
    url: jdbc:mysql://${db.host:localhost}:${db.port:3306}/${db.name:loopschool}?useSSL=false
    username: ${db.uid:root}
    password: ${db.pwd:}
    driver-class-name: com.mysql.cj.jdbc.Driver
    tomcat:
      test-while-idle: true
      validation-query: SELECT 1
  jpa:
    properties:
      hibernate:
        dialect: org.hibernate.dialect.MySQL5Dialect
    hibernate:
      id:
        new_generator_mappings: true
      naming:
        physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
      ddl-auto: validate
  application:
      name: LoopServer
  jmx:
      default-domain: LoopServer
  servlet:
      multipart:
        max-file-size: 30MB
        max-request-size: 100MB
  main:
    allow-bean-definition-overriding: true
check-user-scopes: true
debug: true

1 个答案:

答案 0 :(得分:0)

最后,我解决了这个问题。 问题是在我从Spring Boot 1.5迁移到Spring Boot 2.1.2之后出现的 较早版本中的大多数功能已被弃用,包括访问sessionfactory的方式。

解决方案:  使用以下代码

@Autowired
private EntityManagerFactory entityManagerFactory;

private org.hibernate.Session getCurrentSession(){

    return entityManagerFactory.unwrap(SessionFactory.class).openSession();
}

代替

@Autowired
private SessionFactory sessionFactory;

private org.hibernate.Session getCurrentSession(){
    return sessionFactory.getCurrentSession();
}

我从this链接获得了解决方案