我在Servlet中运行HSQLDB。当我将应用程序重新部署到Web服务器时,.lck文件未正确发布,并且HSQL服务器无法加载该文件。
Web服务器是随NetBeans一起提供的Tomcat 7.0.22 ...
为什么会发生这种情况?
这是初始代码:
@Override public void init() throws ServletException {
HsqlProperties p = new HsqlProperties();
p.setProperty("server.database.0", dbPath);
p.setProperty("server.dbname.0", Environment.PERSISTENCE_HSQL_DB_NAME);
p.setProperty("server.port", Environment.PERSISTENCE_HSQL_PORT);
server = new Server();
server.setProperties(p);
server.setSilent(false);
server.setTrace(true);
server.setLogWriter(new PrintWriter(System.out));
server.setErrWriter(null);
server.start();
server.checkRunning(true);
/* Exception handling */
}
这是我的shutdown / destroy方法:
@Override
public void destroy() {
super.destroy();
server.setNoSystemExit(true);
server.stop();
server.shutdown();
controller.shutdown();
}
我正在使用JPA。如果数据库加载(首次启动),该应用程序正常工作。这是我的persistence.xml:
<persistence-unit name="embedded_hsql" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<!-- Entities -->
<properties>
<property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/>
<property name="hibernate.connection.url" value="jdbc:hsqldb:hsql://localhost:9001/fst_db;hsqldb.lock_file=false"/>
<property name="hibernate.connection.username" value="SA"/>
<property name="hibernate.connection.password" value=""/>
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider"/>
<property name="hibernate.show_sql" value="false"/>
<property name="hibernate.connection.SetBigStringTryClob" value="true"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="current_session_context_class" value="thread" />
<property name="cache.provider_class" value="org.hibernate.cache.NoCacheProvider" />
</properties>
</persistence-unit>
我添加了“hsqldb.lock_file = false”用于测试目的,完全没有效果。一般来说,我不想禁用文件锁定...
谢谢!
答案 0 :(得分:1)
如果您需要从同一个Web应用程序中访问该数据库,那么最好:
这将有助于完全消除hsqldb启动/停止负担。
答案 1 :(得分:0)
嗨,这样解决了问题:
@Override
public void destroy() {
controller.shutdown();
PersistenceUtility.getInstance().closeAllEntityManagers();
try {
EntityManager em = PersistenceUtility.getInstance().createEntityManager();
em.getTransaction().begin();
Query shutdownQuery = em.createNativeQuery("SHUTDOWN");
shutdownQuery.executeUpdate();
em.getTransaction().commit();
} catch (Throwable t) {
Environment.LOGGER.debug("Database connection closed");
}
server.signalCloseAllServerConnections();
server.shutdown();
super.destroy();
}
我唯一的问题是本机查询SHUTDOWN
可以解决问题,但也会触发相应EntityManager
引发的异常。我的理论是,在EntityManager关闭连接之前,数据库已关闭并停止......
如果我打印了cat Throwable t
的堆栈跟踪,我得到:
javax.persistence.PersistenceException: org.hibernate.exception.JDBCConnectionException: could not execute native bulk manipulation query
at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:637)
at org.hibernate.ejb.QueryImpl.executeUpdate(QueryImpl.java:58)
at com.convista.fst.manager.ConfigurationServlet.destroy(ConfigurationServlet.java:115)
at org.apache.catalina.core.StandardWrapper.unload(StandardWrapper.java:1417)
at org.apache.catalina.core.StandardWrapper.stopInternal(StandardWrapper.java:1764)
at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:230)
at org.apache.catalina.core.StandardContext$4.run(StandardContext.java:5449)
at java.lang.Thread.run(Thread.java:722)
Caused by: org.hibernate.exception.JDBCConnectionException: could not execute native bulk manipulation query
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:74)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.engine.query.NativeSQLQueryPlan.performExecuteUpdate(NativeSQLQueryPlan.java:174)
at org.hibernate.impl.SessionImpl.executeNativeUpdate(SessionImpl.java:1163)
at org.hibernate.impl.SQLQueryImpl.executeUpdate(SQLQueryImpl.java:334)
at org.hibernate.ejb.QueryImpl.executeUpdate(QueryImpl.java:49)
... 6 more
Caused by: java.sql.SQLTransientConnectionException: connection exception: connection failure: java.net.SocketException: Software caused connection abort: socket write error
at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
at org.hsqldb.jdbc.JDBCPreparedStatement.close(Unknown Source)
at org.hibernate.jdbc.AbstractBatcher.closePreparedStatement(AbstractBatcher.java:534)
at org.hibernate.jdbc.AbstractBatcher.closeStatement(AbstractBatcher.java:269)
at org.hibernate.engine.query.NativeSQLQueryPlan.performExecuteUpdate(NativeSQLQueryPlan.java:169)
... 9 more
Caused by: org.hsqldb.HsqlException: connection exception: connection failure: java.net.SocketException: Software caused connection abort: socket write error
at org.hsqldb.error.Error.error(Unknown Source)
at org.hsqldb.error.Error.error(Unknown Source)
at org.hsqldb.ClientConnection.execute(Unknown Source)
... 13 more
你知道造成这种例外的原因吗?
答案 2 :(得分:0)
从HSQLDB 2.4.1开始,似乎关闭HSQL服务器的正确方法是通过org.hsqldb.server.Server类的shutdownCatalogs或shutdownWithCatalogs方法。
在您的情况下,这将是:
server.shutdownCatalogs(org.hsqldb.Database.CLOSEMODE_NORMAL);
一个明显的问题是,当最后一个数据库关闭时,stop()最终被调用,然后又调用shutdown(),这导致了一些冗余的内部调用,但这似乎没有害处。 >