也许标题是自我解释的,但我正在尝试使用H2数据库的嵌入式实例创建一个Web应用程序。我正在配置Tomcat 7以使用JDBC领域进行基于表单的身份验证。 server.xml
有:
<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" />
我也在使用Hibernate进行持久化。 persistence.xml
有:
<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" />
如果我尝试启动服务器,我会得到:
(...) Caused by: org.h2.jdbc.JdbcSQLException: Database may be already in use: "Locked by another process".
我的网络应用程序无法启动。
启动H2 TCP服务器并用jdbc:h2:tcp://myIP/
替换JDBC URL工作正常。所以我的数据库文件没问题。此外,我相信没有别的东西试图使用这些文件。所以冲突只能在JDBC领域和Hibernate之间发生。
为什么我需要嵌入式服务器?出于经典原因:我想分发这个应用程序,我不希望用户必须启动两个进程而不只是一个进程。此外,这不是共享数据库,因此不需要为此创建新进程。最后,没有为数据库打开额外的服务器端口,这有利于安全。
答案 0 :(得分:1)
回答我自己的问题,实现这项工作的方法是使用JNDI数据源来访问数据库。对于身份验证,应将Tomcat配置为使用DataSourceRealm。因此,Tomcat安全性和Hibernate都将使用相同的H2嵌入式实例,这不会导致我遇到的冲突。
答案 1 :(得分:0)
虽然JNDI数据源是首选,但最初的问题是您尝试使用文件或嵌入式数据库URL创建到同一H2数据库的两个连接。 H2确实支持这一点,但是这两个进程都需要在连接URL上附加“; AUTO_SERVER = true”。这将导致第一个连接以嵌入模式启动db进程,但允许第二个连接通过tcp ip连接。
详情请见:
http://www.h2database.com/html/features.html#auto_mixed_mode