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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23850585/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 20:33:41  来源:igfitidea点击:

How to start spring-boot app without depending on Database?

mysqlspringjpaspring-boothibernate-4.x

提问by Ripu Daman

I am using "Spring-boot + Hibernate4 + mysql" for my application. As part of which I have a requirement where my sprint-boot app should be able to start even when database is down. Currently it gives the below exception when I try to start my spring boot app without DB being up.

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

I researched a lot and found out that this exception has to do with hibernate.temp.use_jdbc_metadata_defaultsproperty.

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

I tried setting this in "application.yml" of spring boot but this property's value is not being reflected at runtime.

我尝试在 spring boot 的“application.yml”中设置它,但是在运行时没有反映这个属性的值。

Exception Stack Trace:

异常堆栈跟踪:

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.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.perform(EntityManagerFactoryBuilderImpl.java:850)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.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:

应用程序.yml:

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

回答by Ripu Daman

It was indeed a tough nut to crack.

这确实是一个难以破解的难题。

After lot and lot of research and actually debugging the spring-boot, spring, hibernate, tomcat pool, etc to get it done.

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

I do think that it will save lot of time for people trying to achieve this type of requirement.

我确实认为这将为尝试实现此类要求的人们节省大量时间。

Below are the settings required to achieve the following requirement

以下是实现以下要求所需的设置

  1. Spring boot apps will start fine even if DB is down or there is no DB.
  2. Apps will pick up the connections on the fly as DB comes up which means there is no need to restart the web server or redeploy the apps.
  3. There is no need to start the tomcat or redeploy the apps, if DB goes down from running state and comes up again.
  1. 即使数据库关闭或没有数据库,Spring Boot 应用程序也能正常启动。
  2. 应用程序将在数据库启动时即时获取连接,这意味着无需重新启动 Web 服务器或重新部署应用程序。
  3. 如果数据库从运行状态下降并再次出现,则无需启动 tomcat 或重新部署应用程序。

application.yml :

应用程序.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

回答by Stephane Nicoll

I am answering here and will close the issue that you have cross-posted

我在这里回答并将关闭您交叉发布的问题

Any "native" property of the JPA implementation (Hibernate) can be set using the spring.jpa.propertiesprefix as explained here

JPA 实现(休眠)的任何“本机”属性都可以使用spring.jpa.properties前缀设置,如此处所述

I haven't looked much further in the actual issue here but to answer this particular question, you can set that hibernate key as follows

我没有进一步研究这里的实际问题,但要回答这个特定问题,您可以按如下方式设置该休眠键

spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults

回答by Percy Vega

Adding this alone worked for me:

单独添加这个对我有用:

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

Just replace the last part with your database dialect.

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

回答by selami tastan

The solution is really useful for me. Thanks i used file "application.properties" includes following lines:

该解决方案对我来说非常有用。谢谢我使用的文件“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

But, you can not use @Transactional annotation at class level

但是,您不能在类级别使用 @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 ...
}

回答by smartwjw

Add following config should be work:

添加以下配置应该可以工作:

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

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