73 votes

Comment configurer spring-boot pour utiliser une base de données H2 basée sur des fichiers ?

J'ai créé avec succès une application Spring Boot qui utilise la base de données intégrée H2 en mémoire. Je voudrais maintenant la transformer en une version basée sur un fichier qui persistera.

J'ai essayé de changer le spring.datasource.* dans mon application.properties et ils ressemblent à quelque chose comme ça :

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`  

Il semble que Spring Boot ignore ces paramètres car il démarre comme suit :

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'

Mon pom.xml contient les dépendances suivantes qui peuvent être pertinentes pour ce billet :

<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>

D'après la documentation et un certain nombre de messages, j'ai cru comprendre que la configuration devait fonctionner, mais je n'ai pas eu de chance. Pour éviter certaines erreurs de base, j'ai essayé et vérifié les points suivants :

  1. Les propriétés de mon application se trouvent dans le classspath :
  2. J'ai essayé d'exclure la configuration automatique dans l'annotation. @EnableAutoConfiguration
  3. J'ai essayé d'injecter un dataSource haricot avec des combinaisons d'annotation @Primary , @ConfigurationProperties(prefix = "spring.datasource") et de définir les propriétés de manière programmatique avec DataSourceBuilder . Cela provoque d'autres erreurs liées au type en cours null .

On dirait qu'il me manque un concept clé ou quelque chose comme ça. Quelqu'un peut-il m'aider ?

MISE À JOUR 1 : Extrait de mon rapport de configuration automatique :

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)

`

MISE À JOUR 2 : ajout d'un actionneur et examen du point d'arrivée. /configprops . Ce qui est intéressant ici, c'est que ma configuration a été prise en compte et que la base de données existe mais que lorsque l'application s'exécute, elle n'utilise pas cet élément. dataSource .

"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"
        }
    }

67voto

Avinash Points 2234

J'ajoute cette réponse pour éviter toute confusion et toute recherche supplémentaire.

En fait, j'ai le même problème et aucune des réponses n'a fonctionné pour moi complètement plutôt que le mélange pour certaines réponses a fonctionné.

Voici la configuration minimale requise pour faire persister la base de données H2 dans Spring Boot.

application.properties

# 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

Ici spring.jpa.hibernate.ddl-auto=update fait l'affaire. Rien d'autre n'est nécessaire.

Il n'est pas nécessaire d'ajouter spring-boot-starter-jdbc dans pom.xml

Il n'est pas nécessaire d'ajouter un paramètre dans l'url du jdbc.

2 votes

Cela devrait être la réponse acceptée. L'option spring.jpa.hibernate.ddl-auto=update était tout ce dont j'avais besoin pour que cela fonctionne.

1 votes

Vous pourriez le modifier de application.xml en application.properties (car vous mentionnez spring boot)

46voto

lenicliu Points 629

Se référer à http://www.h2database.com/html/cheatSheet.html

Je pense qu'il y a un problème avec le jdbc.url, changez-le comme ceci :

# 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 votes

Merci, mais la configuration crée effectivement une instance de base de données en cours d'exécution avec l'url correct (comme configuré voir UPDATE 2 ci-dessus). Le problème est que l'application ne l'utilise pas. Elle semble utiliser la base de données par défaut 'EmbeddedDatabase'.

6 votes

Avez-vous ajouté le spring-boot-starter-jdbc dans pom.xml ? voici un exemple de projet : github.com/lenicliu/eg-spring/tree/master/eg-spring-boot/ flyway pour la migration et h2database pour l'intégration de la base de données par mode fichier.

5 votes

L'ajout de spring-boot-starter-jdbc au pom.xml a fonctionné ! Merci. Ce serait génial de savoir pourquoi cela a réglé le problème.

6voto

guntarion Points 51

En utilisant le paramètre suivant dans application.properties, je parviens à conserver la persistance des données même après l'arrêt et le redémarrage de SpringBoot, et même après le redémarrage de l'ordinateur.

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;

Ne pas fermer une base de données lorsque la VM sort Oui, mais ne créez pas non plus une nouvelle base de données si elle existe déjà.

jdbc:h2:<url>;IFEXISTS=TRUE

spring.jpa.hibernate.ddl-auto = update

0 votes

Bonjour @guntarion, veuillez consulter la suggestion de lenicliu ci-dessus. Le problème a été résolu en ajoutant spring-boot-starter-jdbc au pom.xml, ce qui a fonctionné.

2 votes

Oui, j'ai remarqué la suggestion et je l'ai essayée. Mais cela ne fonctionne pas.

2 votes

C'est le paramètre "spring.jpa.hibernate.ddl-auto = update" qui a fait l'affaire pour moi. J'ai essayé tous les autres conseils ici.

0voto

Brian Clozel Points 6473

Je viens de générer un tout nouveau projet Spring Boot avec start.spring.io et quelques dépendances. h2, JPA, web, devtools, actuator . Après avoir ajouté une entité simple et un référentiel Spring Data, la base de données est en effet créée en mémoire par défaut.

J'ajoute ce qui suit à mon application.properties crée définitivement le fichier de la base de données au bon endroit :

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

Je peux même m'y connecter avec la console H2 lorsque devtools est activé. http://localhost:8080/h2-console/ .

La prochaine étape logique est de visiter le http://localhost:8080/autoconfig et vérifier l'état de l'auto-configuration.

Dans mon cas, il s'agit de 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"
}
],

et ce qui suit dans negativeMatches :

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

Pourriez-vous essayer les éléments suivants et vérifier le rapport d'auto-configuration pour ceux-ci ?

0 votes

Bonjour Brian, mes résultats sont inversés par rapport aux vôtres : les correspondances positives incluent 'DataSourceAutoConfiguration.EmbeddedConfiguration' et les correspondances négatives incluent 'DataSourceAutoConfiguration.NonEmbeddedConfiguration'. Le fait que la base de données soit intégrée ne m'inquiète pas, mais le fait que mes données soient stockées dans la base de données en mémoire intégrée par défaut m'inquiète. Je voudrais que les données soient stockées sur l'URL basée sur le fichier que j'ai configuré.

-2voto

Sangram Jadhav Points 1855

Créer un fichier .h2.server.properties dans votre chemin de classe et mettez les choses ci-dessous et essayez de nouveau. Vous pouvez créer ce fichier dans le dossier des ressources.

#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 votes

J'ai essayé cette suggestion en utilisant les deux noms de fichiers .h2.server.properties y h2.server.properties avec le contenu ci-dessus. Aucun des deux n'a eu d'impact.

0 votes

J'ai regardé la documentation de h2 et ce fichier est pour la configuration de la console. Je n'ai aucun problème pour me connecter à la console, ni pour créer mes tables de base de données ou stocker les données. Le problème est que l'URL que l'application utilise pour se connecter à la base de données n'est pas affecté par la configuration du fichier application.properties.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X