web-dev-qa-db-ja.com

H2インメモリデータベース。テーブルが見つかりません

URL "jdbc:h2:test"のH2データベースを持っています。 CREATE TABLE PERSON (ID INT PRIMARY KEY, FIRSTNAME VARCHAR(64), LASTNAME VARCHAR(64));を使用してテーブルを作成します。次に、SELECT * FROM PERSONを使用して、この(空の)テーブルからすべてを選択します。ここまでは順調ですね。

ただし、URLを"jdbc:h2:mem:test"に変更すると、データベースがメモリのみにあるという唯一の違いが、org.h2.jdbc.JdbcSQLException: Table "PERSON" not found; SQL statement: SELECT * FROM PERSON [42102-154]になります。私はおそらくここで簡単なものを見逃していますが、どんな助けもありがたいです。

160
Jorn

hbm2ddlは、テーブルの作成後に接続を閉じるため、h2はそれを破棄します。

このように設定された接続URLがある場合

jdbc:h2:mem:test

最後の接続が閉じられると、データベースのコンテンツは失われます。

コンテンツを保持したい場合は、このようにURLを設定する必要があります

jdbc:h2:mem:test;DB_CLOSE_DELAY=-1

そうする場合、h2vmが存続する限りその内容を保持します。

285
reini2901

私はこれがあなたのケースではないことを知っていますが、すべてのスクリプト(作成スクリプトを含む)で小文字を使用していても、H2が大文字名でテーブルを作成し、大文字と小文字を区別していたため、同じ問題がありました。

接続URLに;DATABASE_TO_UPPER=falseを追加して解決しました。

82
Cristian Vrabie

わかりにくい。これをテストするプログラムを作成しました:

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();
}
}

テストは完了し、失敗も予期せぬ出力もありませんでした。どのバージョンのh2を実行していますか?

10
Joseph Ottinger

H2インメモリデータベースは、JVM内のメモリにデータを格納します。 JVMが終了すると、このデータは失われます。

あなたがしていることは、以下の2つのJavaクラスに似ていると思います。これらのクラスの1つはテーブルを作成し、他のクラスはテーブルに挿入しようとします。

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();
    }
}

そして

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();
    }
}

これらのクラスを次々に実行すると、次の出力が得られました。

 C:\ Users\Luke\stuff> Java CreateTable 
 
 C:\ Users\Luke\stuff> Java InsertIntoTable 
スレッド「main」組織の例外。 h2.jdbc.JdbcSQLException:テーブル「PERSON」が見つかりません。 SQLステートメント:
 INSERT INTO PERSON(ID、FIRSTNAME、LASTNAME)VALUES(1、 'John'、 'Doe')[42102-154] 
 at org.h2.message.DbException.getJdbcSQLException (DbException.Java:327)
 at org.h2.message.DbException.get(DbException.Java:167)
 at org.h2.message.DbException.get(DbException.Java:144 )
 ... 

最初のJavaプロセスが終了するとすぐに、CreateTableによって作成されたテーブルは存在しなくなります。したがって、InsertIntoTableクラスが登場すると、挿入するテーブルがなくなります。

接続文字列をjdbc:h2:testに変更すると、そのようなエラーは発生していません。ファイルtest.h2.dbが現れたことも発見しました。これは、H2がテーブルを配置した場所であり、ディスクに保存されていたため、InsertIntoTableクラスが検索するためにテーブルはまだそこにありました。

6
Luke Woodward

私は追加しようとしました

jdbc:h2:mem:test;DB_CLOSE_DELAY=-1

しかし、それは助けにはなりませんでした。 H2サイト で、私は以下を見つけました。

デフォルトでは、データベースへの最後の接続を閉じるとデータベースが閉じます。インメモリデータベースの場合、これはコンテンツが失われることを意味します。データベースを開いたままにするには、; DB_CLOSE_DELAY = -1をデータベースURLに追加します。仮想マシンが動作している限り、インメモリデータベースのコンテンツを保持するには、jdbc:h2:mem:test; DB_CLOSE_DELAY = -1を使用します。

ただし、、私の問題は、スキーマだけがデフォルトのものとは異なるはずであるということでした。だから使用する

JDBC URL: jdbc:h2:mem:test

私は使用しなければなりませんでした:

JDBC URL: jdbc:h2:mem:testdb

その後、テーブルが表示されました

4
DevDio

同じエラーが発生したため、この投稿に行きました。

私の場合、データベースの進化は実行されなかったため、テーブルはまったくありませんでした。

私の問題は、進化スクリプトのフォルダー構造が間違っていたことです。

from: https://www.playframework.com/documentation/2.0/Evolutions

Playは、いくつかの進化スクリプトを使用してデータベースの進化を追跡します。これらのスクリプトは単純な古いSQLで記述されており、アプリケーションのconf/evolutions/{database name}ディレクトリに配置する必要があります。進化がデフォルトのデータベースに適用される場合、このパスはconf/evolutions/defaultです。

Eclipseによって作成されたconf/evolutions.defaultというフォルダーがありました。フォルダー構造をconf/evolutions/defaultに修正すると、問題はなくなりました

1
Oscar Fraxedas

テーブルのメタデータを取得しようとしましたが、次のエラーが発生しました:

を使用して:

String JDBC_URL = "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1";

DatabaseMetaData metaData = connection.getMetaData();
...
metaData.getColumns(...);

空のResultSetを返しました。

ただし、代わりに次のURLを使用すると、正常に機能しました。

String JDBC_URL = "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false";

指定する必要がありました:DATABASE_TO_UPPER = false

私は同じ問題を抱えていて、application-test.propertiesの構成を次のように変更しました。

#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

そして私の依存関係:

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

そして、テストクラスで使用される注釈:

@RunWith(SpringRunner.class)
@DataJpaTest
@ActiveProfiles("test")
public class CommentServicesIntegrationTests {
...
}
1
Georgi Peev
<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>
0
Alex R

H2-consoleを開くとき、JDBC URLはプロパティで指定されたURLと一致する必要があります。

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

enter image description here

当たり前のように思えますが、これを理解するのに何時間も費やしました。

0
nagy.zsolt.hun

新しいsrc/test/resourcesフォルダーを作成してapplication.propertiesファイルを挿入し、テストdbaseの作成を明示的に指定することで解決しました。

spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=create
0
N.MATHIEU