Вопрос

Perhaps the title is self explanatory, but I am trying to create a web application with an embedded instance of the H2 database. I am configuring Tomcat 7 to use the JDBC realm to form-based authentication. server.xml has:

<Realm className="org.apache.catalina.realm.JDBCRealm"
driverName="org.h2.Driver"
connectionURL="jdbc:h2:/someDir/myDB"
connectionName="userName"
connectionPassword="password"
userTable="user_enabled"
userNameCol="user_name"
userCredCol="pass"
userRoleTable="user_role"
roleNameCol="role_name" />

I am also using Hibernate for persistence. persistence.xml has:

<property name="hibernate.connection.driver_class" value="org.h2.Driver" />
<property name="hibernate.connection.url" value="jdbc:h2:/someDir/myDB" />
<property name="hibernate.connection.username" value="userName" />
<property name="hibernate.connection.password" value="password" />
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" />
<property name="hibernate.hbm2ddl.auto" value="validate" />
<property name="hibernate.show_sql" value="true" />
<property name="current_session_context_class" value="org.hibernate.context.internal.ThreadLocalSessionContext" />

If I try to start the server I get:

(...) Caused by: org.h2.jdbc.JdbcSQLException: Database may be already in use: "Locked by another process".

And my web application fails to start.

Starting an H2 TCP server and replacing JDBC URLs with jdbc:h2:tcp://myIP/ works fine. So no problem with my database files. Also, I am sure nothing else is trying to use those files. So the conflict can only be between the JDBC realm and Hibernate.

Why do I want an embedded server? For the classic reasons: I want to distribute this application and I don't want users to have to start two processes instead of just one. Also, this will not be a shared database, so no need to create a new process just for that. Finally, no additional server ports are open for database, which is good for security.

Это было полезно?

Решение

Answering my own question, the way to make this work is by using a JNDI data source to access the database. For authentication, Tomcat should be configured to use the DataSourceRealm. So both Tomcat security and Hibernate will use the same embedded instance of H2, which does not cause the conflict I was experiencing.

Другие советы

Though the JNDI data source is preferable, the original issue is that you are trying to create two connections to the same H2 database using a file or embedded database url. H2 does support this, but both of the processes would need to have ";AUTO_SERVER=true" appended to the connection url. This would cause the first connection to start the db in process in embedded mode, but would allow the seccond connection to connect through tcp ip.

Details are available here:

http://www.h2database.com/html/features.html#auto_mixed_mode

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top