URL이있는 H2 데이터베이스가 "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]
. 아마도 여기에 간단한 것이 빠져 있지만 도움이 될 것입니다.
답변
DB_CLOSE_DELAY=-1
hbm2ddl은 테이블을 생성 한 후 연결을 닫으므로 h2는 삭제합니다.
연결 URL을 다음과 같이 구성한 경우
jdbc:h2:mem:test
마지막 연결이 닫히는 순간 데이터베이스의 내용이 손실됩니다.
콘텐츠를 유지하려면 다음과 같이 URL을 구성해야합니다
jdbc:h2:mem:test;DB_CLOSE_DELAY=-1
그렇게하면 h2 는 vm 이 유지되는 동안 내용을 유지합니다 .
콜론 ( ;
)이 아니라 세미콜론 ( )을 확인 하십시오 :
.
참고 항목 인 – 메모리 데이터베이스 의 섹션 기능 페이지를. 인용 :
기본적으로 데이터베이스에 대한 마지막 연결을 닫으면 데이터베이스가 닫힙니다. 인 메모리 데이터베이스의 경우 이는 내용이 손실되었음을 의미합니다. 데이터베이스를 열어 두려면
;DB_CLOSE_DELAY=-1
데이터베이스 URL에 추가하십시오 . 가상 머신이 활성 상태 인 한 인 메모리 데이터베이스의 컨텐츠를 유지하려면을 사용하십시오jdbc:h2:mem:test;DB_CLOSE_DELAY=-1
.
답변
나는 이것이 당신의 경우가 아니라는 것을 알고 있지만 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 인 메모리 데이터베이스는 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 스레드 "main"의 예외 org.h2.jdbc.JdbcSQLException : "PERSON"테이블을 찾을 수 없습니다. SQL 문 : 사람 (ID, 성, 이름)에 삽입 (1, 'John', 'Doe') [42102-154] org.h2.message.DbException.getJdbcSQLException (DbException.java:327)에서 org.h2.message.DbException.get (DbException.java:167)에서 org.h2.message.DbException.get (DbException.java:144)에서 ...
첫 번째 java
프로세스가 종료 되 자마자 생성 한 테이블이 CreateTable
더 이상 존재하지 않습니다. 따라서 InsertIntoTable 클래스가 나오면 삽입 할 테이블이 없습니다.
연결 문자열을로 변경하면 jdbc:h2:test
이러한 오류가 없음을 발견했습니다. 나는 또한 파일 test.h2.db
이 나타났음을 발견했다 . 이것은 H2가 테이블을 넣은 위치였으며 디스크에 저장되었으므로 InsertIntoTable 클래스를 찾을 수있는 테이블이 여전히있었습니다.
답변
나는 추가하려고했습니다
jdbc:h2:mem:test;DB_CLOSE_DELAY=-1
그러나 그것은 도움이되지 못했습니다. 온 H2 사이트 , 난 정말 어떤 경우에 도움이 될 다음을 발견했다.
기본적으로 데이터베이스에 대한 마지막 연결을 닫으면 데이터베이스가 닫힙니다. 인 메모리 데이터베이스의 경우 이는 내용이 손실되었음을 의미합니다. 데이터베이스를 열어 두려면; DB_CLOSE_DELAY = -1을 데이터베이스 URL에 추가하십시오. 가상 머신이 활성 상태 인 한 인 메모리 데이터베이스의 컨텐츠를 유지하려면 jdbc : h2 : mem : test; DB_CLOSE_DELAY = -1을 사용하십시오.
그러나 내 문제는 스키마 만 기본 스키마와 달라야한다는 것입니다. 그래서 사용의 insted
JDBC URL: jdbc:h2:mem:test
나는 사용해야했다 :
JDBC URL: jdbc:h2:mem:testdb
그런 다음 테이블이 보입니다.
답변
나는 같은 문제가 있었고 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 {
...
}
답변
테이블 메타 데이터를 가져 오려고했지만 다음 오류가 발생했습니다.
사용 :
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 를 지정해야했습니다.