J'ai une base de données H2 avec une URL "jdbc:h2:test"
. Je crée une table en utilisant CREATE TABLE PERSON (ID INT PRIMARY KEY, FIRSTNAME VARCHAR(64), LASTNAME VARCHAR(64));
. Je sélectionne ensuite tout dans cette table (vide) en utilisant SELECT * FROM PERSON
. Jusqu'ici tout va bien.
Cependant, si je change l'URL en "jdbc:h2:mem:test"
, la seule différence étant que la base de données est maintenant uniquement en mémoire, cela me donne un org.h2.jdbc.JdbcSQLException: Table "PERSON" not found; SQL statement: SELECT * FROM PERSON [42102-154]
. Il me manque probablement quelque chose de simple ici, mais toute aide serait appréciée.
Person
. H2 ne sait rien de la base de données que vous avez créée sur le disque auparavant.Réponses:
DB_CLOSE_DELAY=-1
hbm2ddl ferme la connexion après avoir créé la table, donc h2 la rejette.
Si votre URL de connexion est configurée comme ceci
le contenu de la base de données est perdu au moment où la dernière connexion est fermée.
Si vous souhaitez conserver votre contenu, vous devez configurer l'URL comme ceci
jdbc:h2:mem:test;DB_CLOSE_DELAY=-1
Si tel est le cas, h2 conservera son contenu aussi longtemps que la VM vivra.
Notez le point-virgule (
;
) plutôt que deux-points (:
).Consultez la section Bases de données en mémoire de la page Fonctionnalités . Citer:
la source
jdbc:h2:mem:;DB_CLOSE_DELAY=-1
ne fonctionne pas.Je sais que ce n'était pas votre cas, mais j'ai eu le même problème car H2 créait les tables avec des noms MAJUSCULES puis se comportait en tenant compte de la casse, même si dans tous les scripts (y compris ceux de création), j'utilisais des minuscules.
Résolu en ajoutant
;DATABASE_TO_UPPER=false
à l'URL de connexion.la source
DATABASE_TO_UPPER=false
chose comme une instruction SQL dans un script d'initialisation? (De même comme une déclaration commeSET MODE PostgreSQL;
) Si oui, quelle est la syntaxe exacte?Dur à dire. J'ai créé un programme pour tester ceci:
package com.gigaspaces.compass; import org.testng.annotations.Test; import java.sql.*; public class H2Test { @Test public void testDatabaseNoMem() throws SQLException { testDatabase("jdbc:h2:test"); } @Test public void testDatabaseMem() throws SQLException { testDatabase("jdbc:h2:mem:test"); } private void testDatabase(String url) throws SQLException { Connection connection= DriverManager.getConnection(url); Statement s=connection.createStatement(); try { s.execute("DROP TABLE PERSON"); } catch(SQLException sqle) { System.out.println("Table not found, not dropping"); } s.execute("CREATE TABLE PERSON (ID INT PRIMARY KEY, FIRSTNAME VARCHAR(64), LASTNAME VARCHAR(64))"); PreparedStatement ps=connection.prepareStatement("select * from PERSON"); ResultSet r=ps.executeQuery(); if(r.next()) { System.out.println("data?"); } r.close(); ps.close(); s.close(); connection.close(); } }
Le test s'est terminé, sans échec ni sortie inattendue. Quelle version de h2 utilisez-vous?
la source
La base de données en mémoire H2 stocke les données en mémoire dans la JVM. Lorsque la JVM se ferme, ces données sont perdues.
Je soupçonne que ce que vous faites est similaire aux deux classes Java ci-dessous. L'une de ces classes crée une table et l'autre essaie de s'y insérer:
import java.sql.*; public class CreateTable { public static void main(String[] args) throws Exception { DriverManager.registerDriver(new org.h2.Driver()); Connection c = DriverManager.getConnection("jdbc:h2:mem:test"); PreparedStatement stmt = c.prepareStatement("CREATE TABLE PERSON (ID INT PRIMARY KEY, FIRSTNAME VARCHAR(64), LASTNAME VARCHAR(64))"); stmt.execute(); stmt.close(); c.close(); } }
et
import java.sql.*; public class InsertIntoTable { public static void main(String[] args) throws Exception { DriverManager.registerDriver(new org.h2.Driver()); Connection c = DriverManager.getConnection("jdbc:h2:mem:test"); PreparedStatement stmt = c.prepareStatement("INSERT INTO PERSON (ID, FIRSTNAME, LASTNAME) VALUES (1, 'John', 'Doe')"); stmt.execute(); stmt.close(); c.close(); } }
Lorsque j'ai exécuté ces classes les unes après les autres, j'ai obtenu le résultat suivant:
Dès que le premier
java
processus se termine, la table créée parCreateTable
n'existe plus. Ainsi, lorsque la classe InsertIntoTable arrive, il n'y a pas de table dans laquelle l'insérer.Lorsque j'ai changé les chaînes de connexion en
jdbc:h2:test
, j'ai constaté qu'il n'y avait pas une telle erreur. J'ai également constaté qu'un fichiertest.h2.db
était apparu. C'était là que H2 avait mis la table, et comme elle avait été stockée sur le disque, la table était toujours là pour que la classe InsertIntoTable la trouve.la source
registerDriver()
appel n'est pas nécessaire: Tout d'abord: un simple Class.forName () fait la même chose pour la plupart des pilotes JDBC et (plus important encore) il est complètement inutile pour Java 6 et up, qui détecte automatiquement les pilotes JDBC (compatibles) sur le classpath.J'ai essayé d'ajouter
jdbc:h2:mem:test;DB_CLOSE_DELAY=-1
Cependant, cela n'a pas aidé. Sur le site H2 , j'ai trouvé des suivis, qui pourraient en effet aider dans certains cas.
Cependant , mon problème était que seul le schéma était censé être différent de celui par défaut. Tellement instable d'utiliser
J'ai dû utiliser:
Puis les tables étaient visibles
la source
J'ai eu le même problème et j'ai changé ma configuration dans application-test.properties en ceci:
#Test Properties spring.datasource.driverClassName=org.h2.Driver spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1 spring.datasource.username=sa spring.datasource.password= spring.jpa.hibernate.ddl-auto=create-drop
Et mes dépendances:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- https://mvnrepository.com/artifact/com.h2database/h2 --> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>1.4.198</version> <scope>test</scope> </dependency>
Et les annotations utilisées sur la classe de test:
@RunWith(SpringRunner.class) @DataJpaTest @ActiveProfiles("test") public class CommentServicesIntegrationTests { ... }
la source
J'essayais de récupérer les métadonnées de la table, mais j'ai eu l'erreur suivante:
En utilisant:
String JDBC_URL = "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1"; DatabaseMetaData metaData = connection.getMetaData(); ... metaData.getColumns(...);
a renvoyé un ResultSet vide.
Mais en utilisant l'URL suivante à la place, cela a fonctionné correctement:
String JDBC_URL = "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false";
Il était nécessaire de spécifier: DATABASE_TO_UPPER = false
la source
Lors de l'ouverture de la console h2, l'URL JDBC doit correspondre à celle spécifiée dans les propriétés:
spring.datasource.driverClassName=org.h2.Driver spring.datasource.url=jdbc:h2:mem:testdb spring.jpa.hibernate.ddl-auto=create spring.jpa.show-sql=true spring.h2.console.enabled=true
Ce qui semble évident, mais j'ai passé des heures à comprendre cela.
la source
Résolu en créant un nouveau dossier src / test / resources + insérez le fichier application.properties, en spécifiant explicitement de créer une base de données de test:
spring.jpa.generate-ddl=true spring.jpa.hibernate.ddl-auto=create
la source
Je suis venu à ce poste parce que j'ai eu la même erreur.
Dans mon cas, les évolutions de la base de données n'ont pas été exécutées, donc la table n'y était pas du tout.
Mon problème était que la structure des dossiers pour les scripts d'évolution était incorrecte.
depuis: https://www.playframework.com/documentation/2.0/Evolutions
J'avais un dossier appelé conf / evolutions.default créé par eclipse. Le problème a disparu après avoir corrigé la structure des dossiers en conf / evolutions / default
la source
Eu exactement le même problème, essayé tout ce qui précède, mais sans succès. La cause plutôt amusante de l'erreur était que la machine virtuelle Java avait démarré trop rapidement, avant la création de la table DB (en utilisant un fichier data.sql dans src.main.resources). J'ai donc mis une minuterie Thread.sleep (1000) pour attendre juste une seconde avant d'appeler "select * from person". Fonctionne parfaitement maintenant.
application.properties:
spring.h2.console.enabled=true spring.datasource.url=jdbc:h2:mem:testdb spring.datasource.driverClassName=org.h2.Driver spring.datasource.username=sa spring.datasource.password=
data.sql:
create table person ( id integer not null, name varchar(255) not null, location varchar(255), birth_date timestamp, primary key(id) ); insert into person values ( 10001, 'Tofu', 'home', sysdate() );
PersonJdbcDAO.java:
public List<Person> findAllPersons(){ return jdbcTemplate.query("select * from person", new BeanPropertyRowMapper<Person>(Person.class)); }
classe principale:
Thread.sleep(1000); logger.info("All users -> {}", dao.findAllPersons());
la source
Je l'ai trouvé fonctionnant après avoir ajouté la dépendance de Spring Data JPA sur la version 2.2.6 de Spring Boot.
Ajouter la configuration H2 DB dans application.yml -
spring: datasource: driverClassName: org.h2.Driver initialization-mode: always username: sa password: '' url: jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE h2: console: enabled: true path: /h2 jpa: database-platform: org.hibernate.dialect.H2Dialect hibernate: ddl-auto: none
la source
<bean id="benchmarkDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="org.h2.Driver" /> <property name="url" value="jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1" /> <property name="username" value="sa" /> <property name="password" value="" /> </bean>
la source
J'ai trouvé la solution en ajoutant cette configuration:
La configuration complète (avec simple spring.datasource.url):
Je travaille avec h2 version 1.4.200 et Spring-Boot 2.2.6.RELEASE
la source
J'ai essayé la solution ci-dessus, mais dans mon cas, comme suggéré dans la console, j'ai ajouté la propriété DB_CLOSE_ON_EXIT = FALSE , cela a résolu le problème.
spring.datasource.url=jdbc:h2:mem:testdb;DATABASE_TO_UPPER=false;DB_CLOSE_ON_EXIT=FALSE
la source
Time.sleep (1000);
C'est du travail pour moi. Juste pour essayer, si votre PC est lent, vous pouvez augmenter la durée du thread pour que DB fonctionne correctement et que JVM puisse obtenir notre table.
la source