2016-06-19 30 views
23

Ho creato con successo un'applicazione di avvio a molla che utilizza il database incorporato di H2 in memoria. Vorrei ora cambiare questo in una versione basata su file che persisterà.Come configurare spring-boot per utilizzare il database H2 basato su file

Ho provato solo cambiando lo spring.datasource * immobili a mio file application.properties e simile a questo:.

spring.datasource.url=jdbc:h2:file:~/test;DB_CLOSE_ON_EXIT=FALSE spring.datasource.username=test spring.datasource.password=test spring.datasource.driverClassName=org.h2.Driver

Sembra avvio primavera appena ignora queste impostazioni, perché solo inizia come segue:

o.s.j.d.e.EmbeddedDatabaseFactory  : Starting embedded database: url='jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false', username='sa' 

mio pom.xml contiene le seguenti dipendenze che possono essere rilevanti per questo post:

<parent> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-starter-parent</artifactId> 
    <version>1.3.5.RELEASE</version> 
</parent> 
.... 
<dependency> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-starter-web</artifactId> 
</dependency> 
<dependency> 
    <groupId>com.h2database</groupId> 
    <artifactId>h2</artifactId> 
</dependency> 
<dependency> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-devtools</artifactId> 
</dependency> 

La mia comprensione dalla documentazione e un numero di post è che la configurazione dovrebbe funzionare, ma senza fortuna per me. Proprio per evitare alcuni degli errori di base che ho provato e controllato i seguenti:

  1. mie proprietà di applicazione è nella classspath:
  2. ho cercato di escludere la configurazione automatica in annotazione @EnableAutoConfiguration
  3. ho ha provato a iniettare un bean DataSource con combinazioni di annotazioni @Primary, @ConfigurationProperties (prefix = "spring.datasource") e imposta le proprietà a livello di codice con DataSourceBuilder. Ciò fa sì che altri errori relativi al tipo siano nulli.

Sembra che manchi un concetto chiave o qualcosa del genere. Qualcuno può aiutare.

UPDATE 1: Estrarre dal mio rapporto di configurazione automatica:

Positive matches: 
----------------- 

    DataSourceAutoConfiguration matched 
    - @ConditionalOnClass classes found: javax.sql.DataSource,org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType (OnClassCondition) 

    DataSourceAutoConfiguration.DataSourceInitializerConfiguration matched 
    - @ConditionalOnMissingBean (types: org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer; SearchStrategy: all) found no beans (OnBeanCondition) 

    DataSourceAutoConfiguration.EmbeddedConfiguration matched 
    - embedded database H2 detected (DataSourceAutoConfiguration.EmbeddedDataSourceCondition) 
    - @ConditionalOnMissingBean (types: javax.sql.DataSource,javax.sql.XADataSource; SearchStrategy: all) found no beans (OnBeanCondition) 

    DataSourceAutoConfiguration.JdbcTemplateConfiguration matched 
    - existing auto database detected (DataSourceAutoConfiguration.DataSourceAvailableCondition) 

    DataSourceAutoConfiguration.JdbcTemplateConfiguration#jdbcTemplate matched 
    - @ConditionalOnMissingBean (types: org.springframework.jdbc.core.JdbcOperations; SearchStrategy: all) found no beans (OnBeanCondition) 

    DataSourceAutoConfiguration.JdbcTemplateConfiguration#namedParameterJdbcTemplate matched 
    - @ConditionalOnMissingBean (types: org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; SearchStrategy: all) found no beans (OnBeanCondition) 

    DataSourceTransactionManagerAutoConfiguration matched 
    - @ConditionalOnClass classes found: org.springframework.jdbc.core.JdbcTemplate,org.springframework.transaction.PlatformTransactionManager (OnClassCondition) 

    DataSourceTransactionManagerAutoConfiguration.TransactionManagementConfiguration matched 
    - @ConditionalOnMissingBean (types: org.springframework.transaction.annotation.AbstractTransactionManagementConfiguration; SearchStrategy: all) found no beans (OnBeanCondition) 

    H2ConsoleAutoConfiguration matched 
    - @ConditionalOnClass classes found: org.h2.server.web.WebServlet (OnClassCondition) 
    - found web application StandardServletEnvironment (OnWebApplicationCondition) 
    - matched (OnPropertyCondition) 

    HibernateJpaAutoConfiguration matched 
    - @ConditionalOnClass classes found: org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean,org.springframework.transaction.annotation.EnableTransactionManagement,javax.persistence.EntityManager (OnClassCondition) 
    - found HibernateEntityManager class (HibernateJpaAutoConfiguration.HibernateEntityManagerCondition) 

Negative matches: 
----------------- 

    DataSourceAutoConfiguration.NonEmbeddedConfiguration did not match 
    - missing supported DataSource (DataSourceAutoConfiguration.NonEmbeddedDataSourceCondition) 

`

UPDATE 2: Attuatore aggiunto e guardò endpoint/configprops. Ciò che è interessante qui è che la mia configurazione è stata presa e il database esiste ma quando l'applicazione viene eseguita non usa questa fonte dati.

"spring.datasource.CONFIGURATION_PROPERTIES": 
    {"prefix":"spring.datasource", 
    "properties":{ 
     "schema":null, 
     "data":null, 
     "xa":{"dataSourceClassName":null, 
       "properties":{} 
      }, 
     "type":null, 
     "separator":";", 
     "url":"jdbc:h2:file:~/test;DB_CLOSE_ON_EXIT=FALSE", 
     "platform":"all", 
     "continueOnError":false, 
     "jndiName":null,    
     "sqlScriptEncoding":null, 
     "password":"******", 
     "name":"testdb", 
     "driverClassName":"org.h2.Driver", 
     "initialize":true, 
     "username":"test" 
     } 
    } 

risposta

15

Fare riferimento alla http://www.h2database.com/html/cheatSheet.html

Credo che potrebbe essere un problema con il jdbc.url, cambiare in questo modo:

# from: 
spring.datasource.url=jdbc:h2:file:~/test;DB_CLOSE_ON_EXIT=FALSE 

# to: 
spring.datasource.url=jdbc:h2:~/test;DB_CLOSE_ON_EXIT=FALSE 
+0

grazie ma la configurazione crea effettivamente un'istanza di database in esecuzione con l'url corretto (come configurato, vedi UPDATE 2 sopra). Il problema è che l'applicazione non la sta usando.Sembra che stia usando l'EmbeddedDatabase di default – bitboy

+4

hai aggiunto spring-boot-starter-jdbc in pom.xml? qui è un progetto di esempio: https://github.com/lenicliu/eg-spring/tree/master/eg-spring-boot/eg-spring-boot-flyway, flyway per la migrazione e h2database per il database embed dalla modalità file. – lenicliu

+3

Aggiunta di spring-boot-starter-jdbc a pom.xml ha funzionato! Grazie. Sarebbe bello sapere perché questo l'ha risolto. – bitboy

-2

Creare un file .h2.server.properties nel vostro percorso di classe e mettere sotto le cose e riprovare. È possibile creare questo file nella cartella delle risorse.

#H2 Server Properties 
0=H2 File|org.h2.Driver|jdbc\:h2\:file\:~/test;DB_CLOSE_ON_EXIT=FALSE 

# Enable if you want other applications to connect 
#webAllowOthers=true 
#webPort=8082 
#webSSL=false 
+0

Ho provato questo suggerimento utilizzando entrambi i nomi di file **. H2.server.properties ** e ** h2.server.properties ** con il contenuto sopra. Nessuno dei due ha avuto un impatto. – bitboy

+0

ha dato un'occhiata alla documentazione di h2 e questo file è per la configurazione della console. Non ho problemi di connessione alla console o alle mie tabelle di database create o ai dati memorizzati. Il problema è che l'url che l'applicazione utilizza per connettersi al database non è influenzato dalla configurazione di application.properties. – bitboy

0

appena generato un nuovo progetto di primavera Boot marchio con start.spring.io con alcune dipendenze h2, JPA, web, devtools, actuator. Dopo aver aggiunto un semplice repository Entity e Spring Data, il database viene effettivamente creato in memoria per impostazione predefinita.

L'aggiunta dei seguenti alla mia application.properties crea sicuramente il file di database nel posto giusto:

spring.datasource.url=jdbc:h2:file:~/test;DB_CLOSE_ON_EXIT=FALSE 
spring.datasource.username=test 
spring.datasource.password=test 
spring.datasource.driverClassName=org.h2.Driver 

posso anche connettersi ad esso con la console H2 quando devtools è abilitato http://localhost:8080/h2-console/.

Il prossimo passo logico è visitare l'endpoint http://localhost:8080/autoconfig e controllare lo stato di configurazione automatica.

Nel mio caso, il seguente è positiveMatches:

DataSourceAutoConfiguration.NonEmbeddedConfiguration: [ 
{ 
    condition: "DataSourceAutoConfiguration.NonEmbeddedDataSourceCondition", 
    message: "supported DataSource class found" 
}, 
{ 
    condition: "OnBeanCondition", 
    message: "@ConditionalOnMissingBean (types: javax.sql.DataSource,javax.sql.XADataSource; SearchStrategy: all) found no beans" 
} 
], 

e di seguito nel negativeMatches:

DataSourceAutoConfiguration.EmbeddedConfiguration: [ 
{ 
    condition: "DataSourceAutoConfiguration.EmbeddedDataSourceCondition", 
    message: "existing non-embedded database detected" 
} 
], 

Potrebbe provare la seguente e controllare il rapporto di configurazione automatica per chi?

+0

Ciao Brian, il mio è un tuo contrario: le corrispondenze positive includono "DataSourceAutoConfiguration.EmbeddedConfiguration" e le corrispondenze negative includono "DataSourceAutoConfiguration.NonEmbeddedConfiguration". Non sono preoccupato del fatto che il DB sia incorporato, ma sono preoccupato che i miei dati siano memorizzati nel database predefinito incorporato nella memoria. Desidero che i dati vengano archiviati nell'URL di file che ho configurato. – bitboy

1

Utilizzando la seguente impostazione application.properties, riesco a mantenere i dati persistito anche dopo aver chiuso e riavviato SpringBoot e anche dopo aver riavviato il computer.

spring.datasource.name=japodb 
spring.datasource.initialize=false 
spring.datasource.driverClassName=org.h2.Driver 

spring.datasource.url=jdbc:h2:file:~/japodb;DB_CLOSE_ON_EXIT=FALSE;IFEXISTS=TRUE;DB_CLOSE_DELAY=-1; 

non chiudere un database quando il VM Esce, sì, ma anche non fare un nuovo database se è già lì.

jdbc:h2:<url>;IFEXISTS=TRUE 

spring.jpa.hibernate.ddl-auto = update 
+0

Ciao @guntarion, per favore vedi il suggerimento di lenicliu sopra. Il problema è stato risolto aggiungendo spring-boot-starter-jdbc al pom.xml che ha funzionato. – bitboy

+0

Sì, ho notato il suggerimento e l'ho provato. Ma non funziona. – guntarion

+0

E 'stato il "spring.jpa.hibernate.ddl-auto = update" che ha fatto il trucco per me. Ho provato tutti gli altri suggerimenti qui. –

4

Sto aggiungendo questa risposta per evitare confusione e ulteriori ricerche.

In realtà ho lo stesso problema e nessuna delle risposte ha funzionato completamente per me, piuttosto che il mix per alcune risposte funzionanti.

Ecco la configurazione minima richiesta per mantenere H2 db in avvio a molla.

application.xml

# H2 
spring.h2.console.enabled=true 
spring.h2.console.path=/h2 
# Datasource 
spring.datasource.url=jdbc:h2:file:~/spring-boot-h2-db 
spring.datasource.username=sa 
spring.datasource.password= 
spring.datasource.driver-class-name=org.h2.Driver 
spring.jpa.hibernate.ddl-auto=update 

Qui spring.jpa.hibernate.ddl-auto=update fa il trucco. Nient'altro è richiesto.

Non c'è bisogno di aggiungere spring-boot-starter-jdbc in pom.xml

Non c'è bisogno di aggiungere qualsiasi parametro URL JDBC.