如何从 java 开始 H2
How to start H2 from java
我有一个连接到 H2 并使用休眠做一些事情的小应用程序。我已经成功地使 H2 和 Hibernate 一起工作,但我的问题是我必须手动启动 H2,这需要以编程方式完成。我尝试了几件事,但 none 有效。
我试过这个最新的东西
server = Server.createTcpServer("-tcpAllowOthers").start();
我得到这个异常:
java.lang.ExceptionInInitializerError
at com.runtimeload.HibernateUtil.startH2AndBuildSessionFactory(HibernateUtil.java:26)
at com.runtimeload.HibernateUtil.<clinit>(HibernateUtil.java:12)
at com.runtimedataload.RuntimeDataLoadTest.<init>(RuntimeDataLoadTest.java:30)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at org.junit.runners.BlockJUnit4ClassRunner.createTest(BlockJUnit4ClassRunner.java:217)
at org.junit.runners.BlockJUnit4ClassRunner.runReflectiveCall(BlockJUnit4ClassRunner.java:266)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=12=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Caused by: org.hibernate.exception.JDBCConnectionException: Error calling Driver#connect
at org.hibernate.engine.jdbc.connections.internal.BasicConnectionCreator.convert(BasicConnectionCreator.java:122)
at org.hibernate.engine.jdbc.connections.internal.BasicConnectionCreator.convertSqlException(BasicConnectionCreator.java:140)
at org.hibernate.engine.jdbc.connections.internal.DriverConnectionCreator.makeConnection(DriverConnectionCreator.java:58)
at org.hibernate.engine.jdbc.connections.internal.BasicConnectionCreator.createConnection(BasicConnectionCreator.java:75)
at org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl.configure(DriverManagerConnectionProviderImpl.java:106)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:111)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:234)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:206)
at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.buildJdbcConnectionAccess(JdbcServicesImpl.java:260)
at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:94)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:111)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:234)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:206)
at org.hibernate.cfg.Configuration.buildTypeRegistrations(Configuration.java:1887)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1845)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1930)
at com.wkfsfrc.drools.dummy.runtimeload.HibernateUtil.startH2AndBuildSessionFactory(HibernateUtil.java:21)
... 27 more
Caused by: org.h2.jdbc.JdbcSQLException: Wrong user name or password [28000-178]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:344)
at org.h2.message.DbException.get(DbException.java:178)
at org.h2.message.DbException.get(DbException.java:154)
at org.h2.message.DbException.get(DbException.java:143)
at org.h2.engine.Engine.validateUserAndPassword(Engine.java:316)
at org.h2.engine.Engine.createSessionAndValidate(Engine.java:150)
at org.h2.engine.Engine.createSession(Engine.java:125)
at org.h2.server.TcpServerThread.run(TcpServerThread.java:150)
at java.lang.Thread.run(Thread.java:745)
所以这是我现有的代码,如果我手动启动 H2 服务器,它可以正常工作:
hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">org.h2.Driver</property>
<property name="connection.url">jdbc:h2:tcp://localhost/~/test;IFEXISTS=TRUE</property>
<property name="connection.username">sa</property>
<property name="connection.password">sa</property>
<property name="connection.pool_size">5</property>
<property name="dialect">org.hibernate.dialect.H2Dialect</property>
<property name="current_session_context_class">thread</property>
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<property name="show_sql">true</property>
<mapping class="com.runtimeload.Employee"/>
</session-factory>
</hibernate-configuration>
HibernateUtil.java
package com.runtimeload;
import org.h2.tools.Server;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import java.sql.Connection;
import java.sql.DriverManager;
public class HibernateUtil {
private static final SessionFactory sessionFactory = startH2AndBuildSessionFactory();
public static Server server;
private static SessionFactory startH2AndBuildSessionFactory() {
startH2Manually();
try {
return new AnnotationConfiguration()
.configure()
.buildSessionFactory();
} catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
private static final void startH2Manually() {
// this is what I have done so for and does not work
try {
server = Server.createTcpServer("-tcpAllowOthers").start();
Thread.sleep(5000);
}
catch (Exception e) {
System.err.println("h2 server failed to start");
}
}
}
RuntimeDataLoadTest.java
package com.runtimedataload;
import com.KieSessionFactory;
import com.SessionIDs;
import com.runtimeload.HibernateUtil;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.kie.api.runtime.KieSession;
import java.net.URISyntaxException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class RuntimeDataLoadTest {
SessionFactory sf = HibernateUtil.getSessionFactory();
private Connection conn;
@Before
public void createEnv() throws Exception{
Class.forName("org.h2.Driver");
conn = DriverManager.getConnection("jdbc:h2:tcp://localhost/~/test", "sa", "sa");
Statement stat = conn.createStatement();
stat.execute("drop table EMPLOYEE");
stat.execute("create table EMPLOYEE(id int primary key, firstname varchar(255), lastname varchar(255), cellphone varchar(255));");
stat.execute("insert into EMPLOYEE values(3, 'aurel', 'ln', 'cp')");
}
...
}
不介意测试方法,流口水的制作和抽象
谢谢!
这在我的测试用例中对我有用:
JdbcDataSource ds = new JdbcDataSource();
ds.setURL("jdbc:h2:mem:test;MODE=Oracle");
ds.setUser("sa");
ds.setPassword("sa");
RunScript.execute(ds.getConnection(), new FileReader("schema.sql"));
Server server = Server.createWebServer("-webAllowOthers");
server.start();
希望对您有所帮助。
最终我用一个maven插件启动了H2服务器。您将在下面找到源代码:
<plugin>
<groupId>com.btmatthews.maven.plugins.inmemdb</groupId>
<artifactId>inmemdb-maven-plugin</artifactId>
<configuration>
<skip>${skip.unit.tests}</skip>
<monitorPort>11527</monitorPort>
<monitorKey>myKey</monitorKey>
<daemon>true</daemon>
<type>h2</type>
<database>${connection.database}</database>
<username>${connection.username}</username>
<password>${connection.password}</password>
</configuration>
<executions>
<execution>
<id>startH2Server</id>
<goals>
<goal>run</goal>
</goals>
<phase>process-test-classes</phase>
</execution>
<execution>
<id>stopH2Server</id>
<goals>
<goal>stop</goal>
</goals>
<phase>prepare-package</phase>
</execution>
</executions>
</plugin>
顺便说一句,我需要 h2 用于测试目的...
并且连接 url 需要更改为:
<property name="connection.url">jdbc:h2:tcp://localhost:9092/mem:test</property>
其他属性保持不变。
希望这对其他人有所帮助。干杯!
我有一个连接到 H2 并使用休眠做一些事情的小应用程序。我已经成功地使 H2 和 Hibernate 一起工作,但我的问题是我必须手动启动 H2,这需要以编程方式完成。我尝试了几件事,但 none 有效。
我试过这个最新的东西
server = Server.createTcpServer("-tcpAllowOthers").start();
我得到这个异常:
java.lang.ExceptionInInitializerError
at com.runtimeload.HibernateUtil.startH2AndBuildSessionFactory(HibernateUtil.java:26)
at com.runtimeload.HibernateUtil.<clinit>(HibernateUtil.java:12)
at com.runtimedataload.RuntimeDataLoadTest.<init>(RuntimeDataLoadTest.java:30)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at org.junit.runners.BlockJUnit4ClassRunner.createTest(BlockJUnit4ClassRunner.java:217)
at org.junit.runners.BlockJUnit4ClassRunner.runReflectiveCall(BlockJUnit4ClassRunner.java:266)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=12=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Caused by: org.hibernate.exception.JDBCConnectionException: Error calling Driver#connect
at org.hibernate.engine.jdbc.connections.internal.BasicConnectionCreator.convert(BasicConnectionCreator.java:122)
at org.hibernate.engine.jdbc.connections.internal.BasicConnectionCreator.convertSqlException(BasicConnectionCreator.java:140)
at org.hibernate.engine.jdbc.connections.internal.DriverConnectionCreator.makeConnection(DriverConnectionCreator.java:58)
at org.hibernate.engine.jdbc.connections.internal.BasicConnectionCreator.createConnection(BasicConnectionCreator.java:75)
at org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl.configure(DriverManagerConnectionProviderImpl.java:106)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:111)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:234)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:206)
at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.buildJdbcConnectionAccess(JdbcServicesImpl.java:260)
at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:94)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:111)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:234)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:206)
at org.hibernate.cfg.Configuration.buildTypeRegistrations(Configuration.java:1887)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1845)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1930)
at com.wkfsfrc.drools.dummy.runtimeload.HibernateUtil.startH2AndBuildSessionFactory(HibernateUtil.java:21)
... 27 more
Caused by: org.h2.jdbc.JdbcSQLException: Wrong user name or password [28000-178]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:344)
at org.h2.message.DbException.get(DbException.java:178)
at org.h2.message.DbException.get(DbException.java:154)
at org.h2.message.DbException.get(DbException.java:143)
at org.h2.engine.Engine.validateUserAndPassword(Engine.java:316)
at org.h2.engine.Engine.createSessionAndValidate(Engine.java:150)
at org.h2.engine.Engine.createSession(Engine.java:125)
at org.h2.server.TcpServerThread.run(TcpServerThread.java:150)
at java.lang.Thread.run(Thread.java:745)
所以这是我现有的代码,如果我手动启动 H2 服务器,它可以正常工作:
hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">org.h2.Driver</property>
<property name="connection.url">jdbc:h2:tcp://localhost/~/test;IFEXISTS=TRUE</property>
<property name="connection.username">sa</property>
<property name="connection.password">sa</property>
<property name="connection.pool_size">5</property>
<property name="dialect">org.hibernate.dialect.H2Dialect</property>
<property name="current_session_context_class">thread</property>
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<property name="show_sql">true</property>
<mapping class="com.runtimeload.Employee"/>
</session-factory>
</hibernate-configuration>
HibernateUtil.java
package com.runtimeload;
import org.h2.tools.Server;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import java.sql.Connection;
import java.sql.DriverManager;
public class HibernateUtil {
private static final SessionFactory sessionFactory = startH2AndBuildSessionFactory();
public static Server server;
private static SessionFactory startH2AndBuildSessionFactory() {
startH2Manually();
try {
return new AnnotationConfiguration()
.configure()
.buildSessionFactory();
} catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
private static final void startH2Manually() {
// this is what I have done so for and does not work
try {
server = Server.createTcpServer("-tcpAllowOthers").start();
Thread.sleep(5000);
}
catch (Exception e) {
System.err.println("h2 server failed to start");
}
}
}
RuntimeDataLoadTest.java
package com.runtimedataload;
import com.KieSessionFactory;
import com.SessionIDs;
import com.runtimeload.HibernateUtil;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.kie.api.runtime.KieSession;
import java.net.URISyntaxException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class RuntimeDataLoadTest {
SessionFactory sf = HibernateUtil.getSessionFactory();
private Connection conn;
@Before
public void createEnv() throws Exception{
Class.forName("org.h2.Driver");
conn = DriverManager.getConnection("jdbc:h2:tcp://localhost/~/test", "sa", "sa");
Statement stat = conn.createStatement();
stat.execute("drop table EMPLOYEE");
stat.execute("create table EMPLOYEE(id int primary key, firstname varchar(255), lastname varchar(255), cellphone varchar(255));");
stat.execute("insert into EMPLOYEE values(3, 'aurel', 'ln', 'cp')");
}
...
}
不介意测试方法,流口水的制作和抽象
谢谢!
这在我的测试用例中对我有用:
JdbcDataSource ds = new JdbcDataSource();
ds.setURL("jdbc:h2:mem:test;MODE=Oracle");
ds.setUser("sa");
ds.setPassword("sa");
RunScript.execute(ds.getConnection(), new FileReader("schema.sql"));
Server server = Server.createWebServer("-webAllowOthers");
server.start();
希望对您有所帮助。
最终我用一个maven插件启动了H2服务器。您将在下面找到源代码:
<plugin>
<groupId>com.btmatthews.maven.plugins.inmemdb</groupId>
<artifactId>inmemdb-maven-plugin</artifactId>
<configuration>
<skip>${skip.unit.tests}</skip>
<monitorPort>11527</monitorPort>
<monitorKey>myKey</monitorKey>
<daemon>true</daemon>
<type>h2</type>
<database>${connection.database}</database>
<username>${connection.username}</username>
<password>${connection.password}</password>
</configuration>
<executions>
<execution>
<id>startH2Server</id>
<goals>
<goal>run</goal>
</goals>
<phase>process-test-classes</phase>
</execution>
<execution>
<id>stopH2Server</id>
<goals>
<goal>stop</goal>
</goals>
<phase>prepare-package</phase>
</execution>
</executions>
</plugin>
顺便说一句,我需要 h2 用于测试目的...
并且连接 url 需要更改为:
<property name="connection.url">jdbc:h2:tcp://localhost:9092/mem:test</property>
其他属性保持不变。
希望这对其他人有所帮助。干杯!