从spring boot 1.3.8.RELEASE迁移到1.5.2.RELEASE - Neo4jDataAutoConfiguration覆盖默认sessionFactory

时间:2017-03-27 09:09:59

标签: spring-boot spring-data hibernate-5.x spring-boot-test

我有一个有效的春季启动应用程序,我正在尝试从Spring启动1.3.8.RELEASE迁移到1.5.2.RELEASE。在我的工作1.3.8.RELEASE轨道中我已经使用了hibernate 5,即我在y pom中具有以下依赖性

     <dependency> 
         <groupId>org.hibernate</groupId> 
         <artifactId>hibernate-java8</artifactId> 
         <version>${hibernate.version}</version> 
     </dependency> 
使用Spring boot 1.5

这不是必需的,因此我将其更改为默认的hibernate 5依赖项,即hibernate-core并删除版本声明。

<dependency>
     <groupId>org.hibernate</groupId>
      <artifactId>hibernate-core</artifactId>
</dependency>

然而,我无法弄清楚为什么我的测试说:

org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.hibernate.SessionFactory' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1486) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]

我确实配置了会话工厂

@Profile("Development")
@Configuration
@EnableTransactionManagement
@Order(value=1)
public class PersistenceConfigDevelopment {

    @Bean
    public org.apache.commons.dbcp.BasicDataSource dataSourceReadWrite() {

        BasicDataSource dataSource = new BasicDataSource();
        dataSource.setDriverClassName("org.postgresql.Driver");
        dataSource.setUrl("jdbc:postgresql://localhost:5432/testDB");
        dataSource.setUsername("admin");
        dataSource.setPassword("veryBigSecret!");
        dataSource.setInitialSize(20);
        dataSource.setMaxActive(-1);

        return dataSource;
    }


    @Bean
    public org.springframework.orm.hibernate5.LocalSessionFactoryBean sessionFactory() {

        org.springframework.orm.hibernate5.LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
        sessionFactory.setDataSource(this.dataSourceReadWrite());
        sessionFactory.setPackagesToScan("org.testApp");
        sessionFactory.setHibernateProperties(hibernateProperties());

        return sessionFactory;
    }


       @Bean
       public  org.springframework.orm.hibernate5.HibernateTransactionManager  transactionManager() {
          HibernateTransactionManager txManager = new HibernateTransactionManager();
          txManager.setSessionFactory(sessionFactory().getObject());
          return txManager;
       }


       @Bean
       public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
          return new PersistenceExceptionTranslationPostProcessor();
       }



    @Bean
    public  Properties hibernateProperties() {

    return new Properties() {

        {
                setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
                setProperty("hibernate.chach.provider_class", "org.hibernate.cache.NoCacheProvider");
                setProperty("hibernate.show_sql", "true");              
                setProperty("hibernate.hbm2ddl.auto", "create-drop");

                setProperty("hibernate.cache.use_second_level_cache", "false");
                setProperty("hibernate.cache.use_query_cache", "false");

                //isolation level
                setProperty("hibernate.connection.isolation", String.valueOf(Connection.TRANSACTION_SERIALIZABLE));

             }
          };
       }

}

这是我如何开始我的春季启动1.5.2测试:

@RunWith(SpringRunner.class)
@TestExecutionListeners(listeners={ 
                                    DependencyInjectionTestExecutionListener.class,
                                    DirtiesContextTestExecutionListener.class,
                                    WithSecurityContextTestExecutionListener.class 
                                    }
        )
@SpringBootTest(
        classes = {
        SecurityWebApplicationInitializerDevelopment.class, 
        SecurityConfigDevelopment.class, 
        TomcatEmbededDevelopmentProfile.class, 
        Internationalization.class, 
        MVCConfigDevelopment.class,
        PersistenceConfigDevelopment.class,
        } 

    )
@WebAppConfiguration
@ActiveProfiles(TestAppConfigurationProfiles.DEVELOPMENT_PROFILE)
@WithMockUser(username="alice",roles={"USER","ADMIN"} )
public class mainTests { 
     ......

由于某种原因,Spring boot 1.5找不到我的会话工厂。但为什么?我使用错误的依赖吗?我已将Hibernate5会话工厂和事务管理器配置为bean。

以下是我的pom的一部分:

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.2.RELEASE</version>

    </parent>


    <groupId>test</groupId>
    <artifactId>testApp</artifactId>
    <name>testApp</name>
    <version>1.0-SNAPSHOT</version>


    <properties>

        <hibernate.version>5.2.9.Final</hibernate.version>

        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

        <maven-compiler-plugin.version>3.6.1</maven-compiler-plugin.version>
        <maven-source-plugin.version>3.0.1</maven-source-plugin.version>
        <maven-javadoc-plugin.version>2.10.4</maven-javadoc-plugin.version>
        <maven-install-plugin.version>2.5.2</maven-install-plugin.version>
        <maven-assembly-plugin.version>3.0.0</maven-assembly-plugin.version>

        <java.version>1.8</java.version>

        <start-class>org.testApp.core.Application</start-class>

    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.batch</groupId>
            <artifactId>spring-batch-core</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
            <exclusions> 
                <exclusion> 
                    <groupId>org.apache.tomcat</groupId> 
                    <artifactId>tomcat-jdbc</artifactId> 
                </exclusion> 
            </exclusions>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.batch</groupId>
            <artifactId>spring-batch-core</artifactId>
        </dependency>

        <!-- Thymeleaf -->    
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

        <dependency>
            <groupId>nz.net.ultraq.thymeleaf</groupId>
            <artifactId>thymeleaf-layout-dialect</artifactId>
        </dependency>

        <!-- Tomcat -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-core</artifactId>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-websocket</artifactId>
        </dependency>

        <!-- Hibernate -->


        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
        </dependency>

        <!-- Apache -->
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
        </dependency>



        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

      <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-test</artifactId>
        <scope>test</scope>  
      </dependency>
      <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.3</version>
      </dependency>


      <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-neo4j</artifactId>
      </dependency>
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-gemfire</artifactId>
      </dependency>
      <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-dbcp2</artifactId>
      </dependency>
    </dependencies>   

</project>

这是我如何启动我的应用程序

@ComponentScan({"org.testApp.*"})
@Configuration
@EnableAutoConfiguration
@EnableWebSocket
@SpringBootApplication
public class Application extends SpringBootServletInitializer  {
...

2017年3月29日增加

在分析了启动配置后,我找到了一行:

2017-03-29 10:45:01.084  INFO 11022 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Overriding bean definition for bean 'sessionFactory' with a different definition: replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=persistenceConfigDevelopment; factoryMethodName=sessionFactory; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/testApp/config/persistence/PersistenceConfigDevelopment.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration; factoryMethodName=sessionFactory; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfiguration.class]]

我不明白为什么Neo4jDataAutoConfiguration.class会覆盖我的自定义persistenceConfigDevelopment bean。

此外,如果我删除了我的主@EnableAutoConfiguration类上的@SpringBootApplicatioApplication n,那么应用程序启动并且正确的会话工厂正在成功实例化,但随后它失败,因为它不能找到一个bean InternalResourceViewResolver,但这是预期的,因为通常@EnableAutoConfiguration正在处理那些bean。

`Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type` 'org.springframework.web.servlet.view.InternalResourceViewResolver' available

1 个答案:

答案 0 :(得分:1)

我找到了解决问题的方法,即

从引用neo4j的pom中删除了任何东西,即

  <dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-neo4j</artifactId>
  </dependency>

然后将以下排除添加到主应用程序类:

@SpringBootApplication(exclude = JpaRepositoriesAutoConfiguration.class)
public class Application extends SpringBootServletInitializer  {

我还不知道确切的错误在哪里但是我知道当我删除spring-data-neo4j时一切正常并且我的所有测试都通过了。