H2 база данных в памяти. Таблица не найдена



у меня есть база данных H2 с URL "jdbc:h2:test". Я создаю таблицу с помощью 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]. Я, вероятно, пропустил что-то простое здесь, но любая помощь будет оценена по достоинству.

896   7  

7 ответов:

hbm2ddl закрывает соединение после создания таблицы, поэтому h2 отбрасывает его.

Если у вас есть подключение-url настроен следующим образом

jdbc:h2:mem:test

содержимое базы данных теряется в момент закрытия последнего соединения.

Если вы хотите сохранить свой контент, вы должны настроить url-адрес следующим образом

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

Если это так,h2 будет держать свое содержание до тех пор, как vm жизнь.

Я знаю, что это не ваш случай, но у меня была та же проблема, потому что H2 создавал таблицы с именами в верхнем регистре, а затем вел себя с учетом регистра, хотя во всех сценариях (в том числе в создании) я использовал нижний регистр.

решается путем добавления ;DATABASE_TO_UPPER=false к URL-адресу подключения.

трудно сказать. Я создал программу, чтобы проверить это:

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 вы используете?

база данных H2 in-memory хранит данные в памяти внутри JVM. Когда JVM завершает работу, эти данные теряются.

Я подозреваю, что то, что вы делаете, похоже на два класса Java ниже. Один из этих классов создает таблицу, а другой пытается вставить в нее:

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
Exception in thread "main" org.h2.jdbc.JdbcSQLException: Table "PERSON" not found; SQL statement:
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, я обнаружил, что такой ошибки не было. Я также обнаружил, что файл было. Именно здесь H2 поместил таблицу, и поскольку она была сохранена на диске, таблица все еще была там для класса InsertIntoTable, чтобы найти.

Я пытался добавить

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

тогда таблицы были видны

Я пришел на этот пост, потому что у меня была такая же ошибка.

в моем случае эволюция базы данных не была выполнена, поэтому таблицы не было вообще.

моя проблема заключалась в том, что структура папок сценариев эволюции был неправ.

от:https://www.playframework.com/documentation/2.0/Evolutions

воспроизведение отслеживает эволюцию базы данных с помощью нескольких сценариев эволюции. Эти скрипты написаны простым языком старый SQL и должен быть расположен в каталоге conf/evolutions/{имя базы данных} вашего приложения. Если изменения применяются к вашей базе данных по умолчанию, этот путь-conf/evolutions/default.

У меня была папка под названием conf / evolutions.по умолчанию создано eclipse. Проблема исчезла после того, как я исправил структуру папок на conf / evolutions / default

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

Comments

    Ничего не найдено.