使用scheduler-BeanCreationNotAllowedException进行Spring启动:创建名为'entityManagerFactory'的bean时出错:不允许创建Singleton bean

Rav*_*iga 5 java hibernate exception scheduler spring-boot

我们有一个带有调度程序的spring boot项目,它以固定的时间间隔从数据库中读取数据.

在使用maven从STS构建项目时,即使最终构建状态成功,我们在运行测试用例时也会在控制台中出现以下错误.

org.springframework.beans.factory.BeanCreationNotAllowedException:创建名为'entityManagerFactory'的bean时出错:当这个工厂的单例处于销毁状态时不允许使用单例bean创建(不要在destroy方法实现中从BeanFactory请求bean!)at Org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:216)位于org.springframework.beans.factory的org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299). org.springframework.beans.factory.BeanFactoryUtils.beansOfTypeIncludingAncestors(BeanFactoryUtils.java:)中org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:523)的support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) 276)at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.detectPersistenceExceptionTranslators(PersistenceExceptionTra)nslationInterceptor.java:162)org.springframework.data上的org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:145)org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) .gpa.repository.support.CrudMethodMetadataPostProcessor $ CrudMethodMetadataPopulatingMethodIntercceptor.invoke(CrudMethodMetadataPostProcessor.java:122)org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke (ExposeInvocationInterceptor.java:92)org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)位于com.sun的org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207).代理.$ Proxy70.findByTraIdAndTransactionNameAndExecutionTime(未知来源)at

申请文件

@SpringBootApplication
@PropertySource("classpath:application.properties")
@EnableScheduling
public class ProvisioningApplication {

    public static void main(String[] args) {

        SpringApplication.run(ProvisioningApplication.class, args);

    }
}
Run Code Online (Sandbox Code Playgroud)

调度程序文件

BusinessService具有读取数据库的逻辑

@Component
public class SchedulerJob {

    @Autowired
    BusinessService service;

    @Scheduled(fixedRate=300000) //5mnts
    public void schdeule() {
        service.startService();

    }
}
Run Code Online (Sandbox Code Playgroud)

测试文件

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = ProvisioningApplication.class)
public class ProvisioningApplicationTests {

    @Test
    public void contextLoads() {
    }

}
Run Code Online (Sandbox Code Playgroud)

这里的问题是为什么spring boot在构建项目时运行调度程序任务以及它为什么抛出上述异常?

Moh*_*mar 1

Spring Boot中,当您执行 Maven 构建时,默认情况下会运行测试用例。在这种情况下,运行集成测试脚本将尝试连接到您的数据库。因为您没有任何东西可以作为项目中集成测试的一部分来执行。一种可能的解决方案是将您的类ProvisioningApplicationTests声明为抽象这将限制ProvisioningApplicationTests类的实例创建。

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = ProvisioningApplication.class)
public abstract class ProvisioningApplicationTests {
    @Test
    public void contextLoads() {
    }
  }
Run Code Online (Sandbox Code Playgroud)

解决此问题的另一种方法是在 pom.xml 中包含以下代码

<plugins>
   <plugin>
    <artifactId>maven-surefire-plugin</artifactId>
    <configuration>
     <skipTests>false</skipTests>
     <excludes>
      <exclude>**/*IT.java</exclude>
     </excludes>
    </configuration>
   </plugin>
   <plugin>
    <artifactId>maven-failsafe-plugin</artifactId>
    <executions>
     <execution>
      <id>integration-test</id>
      <goals>
       <goal>integration-test</goal>
      </goals>
      <configuration>
       <skipTests>true</skipTests>
       <includes>
        <include>**/*IT.class</include>
       </includes>
      </configuration>
     </execution>
    </executions>
   </plugin>
  </plugins>
Run Code Online (Sandbox Code Playgroud)

这将排除在构建项目时要执行的集成测试类。maven-surefire-plugin用于运行单元测试。maven-failsafe-plugin用于运行集成测试。使用此方法时,请确保所有集成类文件名均以'IT'结尾。例如 UserTestIT.java