如何在不依赖数据库的情况下启动spring-boot应用程序?

时间:2014-05-24 23:20:45

标签: mysql spring jpa spring-boot hibernate-4.x

我正在使用" Spring-boot + Hibernate4 + mysql"为我的申请。作为其中的一部分,我有一个要求,即使数据库关闭,我的sprint-boot应用程序应该能够启动。目前,当我尝试在没有DB启动的情况下启动Spring启动应用程序时,它会给出以下异常。

我研究了很多,发现这个例外与hibernate.temp.use_jdbc_metadata_defaults属性有关。

我尝试在" application.yml"春季启动,但此属性的值未在运行时反映。

异常堆栈跟踪:

2014-05-25 04:09:43.193  INFO 59755 --- [           main] o.hibernate.annotations.common.Version   : HCANN000001: Hibernate Commons Annotations {4.0.4.Final}
2014-05-25 04:09:43.250  WARN 59755 --- [           main] o.h.e.jdbc.internal.JdbcServicesImpl     : HHH000342: Could not obtain connection to query metadata : Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
2014-05-25 04:09:43.263  INFO 59755 --- [           main] o.apache.catalina.core.StandardService   : Stopping service Tomcat

Error starting ApplicationContext. To display the auto-configuration report enabled debug logging (start with --debug)


Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.HibernateException: Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1553)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:973)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:750)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:120)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:648)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:311)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:909)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:898)
    at admin.Application.main(Application.java:36)
Caused by: org.hibernate.HibernateException: Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set
    at org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl.determineDialect(DialectFactoryImpl.java:104)
    at org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl.buildDialect(DialectFactoryImpl.java:71)
    at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:205)
    at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:89)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:206)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:178)
    at org.hibernate.cfg.Configuration.buildTypeRegistrations(Configuration.java:1885)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1843)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:850)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:843)
    at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.withTccl(ClassLoaderServiceImpl.java:399)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:842)
    at org.hibernate.jpa.HibernatePersistenceProvider.createContainerEntityManagerFactory(HibernatePersistenceProvider.java:150)
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:336)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:318)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1612)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1549)
    ... 15 more

application.yml:

spring:   
  jpa:
show-sql: true
hibernate:
  ddl-auto: none
  naming_strategy: org.hibernate.cfg.DefaultNamingStrategy
  temp:
    use_jdbc_metadata_defaults: false

5 个答案:

答案 0 :(得分:49)

破解确实是一个艰难的难题。

经过大量的研究和实际调试spring-boot,spring,hibernate,tomcat pool等来完成它。

我认为这会为试图达到这种要求的人节省大量时间。

以下是达到以下要求所需的设置

  1. 即使数据库已关闭或没有数据库,Spring启动应用程序也会正常运行。
  2. 应用程序会在数据库启动时动态获取连接,这意味着无需重新启动Web服务器或重新部署应用程序。
  3. 如果DB从运行状态下降并再次出现,则无需启动tomcat或重新部署应用程序。
  4. application.yml:

    spring:
      datasource:
        driverClassName: com.mysql.jdbc.Driver
        url: jdbc:mysql://localhost:3306/schema
        username: root
        password: root
        continueOnError: true
        initialize: false
        initialSize: 0
        timeBetweenEvictionRunsMillis: 5000
        minEvictableIdleTimeMillis: 5000
        minIdle: 0
    
      jpa:
        show-sql: true
        hibernate:
          ddl-auto: none
          naming_strategy: org.hibernate.cfg.DefaultNamingStrategy
        properties:
          hibernate:   
            dialect: org.hibernate.dialect.MySQL5Dialect
            hbm2ddl:
              auto: none
            temp:
              use_jdbc_metadata_defaults: false
    

答案 1 :(得分:10)

我在这里回答并将关闭the issue that you have cross-posted

可以使用spring.jpa.properties前缀explained here

设置JPA实现(Hibernate)的任何“原生”属性

我在这里的实际问题上没有进一步了解,但为了回答这个问题,您可以将hibernate键设置如下

spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults

答案 2 :(得分:6)

单独添加此功能对我有用:

spring.jpa.properties.hibernate.dialect: org.hibernate.dialect.Oracle10gDialect

只需用数据库方言替换最后一部分。

答案 3 :(得分:0)

该解决方案对我来说真的很有用。谢谢 我使用的文件“ application.properties”包括以下几行:

    app.sqlhost=192.168.10.11
    app.sqlport=3306
    app.sqldatabase=logs

    spring.main.web-application-type=none

    # Datasource
    spring.datasource.url=jdbc:mysql://${app.sqlhost}:${app.sqlport}/${app.sqldatabase}
    spring.datasource.username=user
    spring.datasource.password=password
    spring.datasource.driver-class-name=com.mysql.jdbc.Driver
    spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
    spring.jpa.properties.hibernate.hbm2dll.auto = none
    spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults = false

    spring.datasource.continue-on-error=true
    spring.datasource.initialization-mode=never

    spring.datasource.hikari.connection-timeout=5000
    spring.datasource.hikari.idle-timeout=600000
    spring.datasource.hikari.max-lifetime=1800000
    spring.datasource.hikari.initialization-fail-timeout= -1

    spring.jpa.hibernate.use-new-id-generator-mappings=true
    spring.jpa.hibernate.ddl-auto=none

    spring.jpa.show-sql=true

    spring.output.ansi.enabled=always

但是,您不能在类级别使用@Transactional注释

@Service
//@Transactional  //do not use to touch the Repository
@EnableAsync
@Scope( proxyMode = ScopedProxyMode.TARGET_CLASS )
public class LogService {
.... }

@Async
@Transactional  // you can use at function level
public void deleteLogs(){
    logRepository.deleteAllBy ...
}

答案 4 :(得分:-1)

添加以下配置应该有效:

spring.jpa.database-platform: org.hibernate.dialect.MySQL5Dialect