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]. Я, вероятно, пропустил что-то простое здесь, но любая помощь будет оценена по достоинству.
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