2012-07-24 7 views
5

Używam HSQLDB wewnątrz serwletu. Kiedy ponownie rozmieszczę aplikację na serwerze sieciowym, plik .lck nie jest poprawnie zwolniony, a serwer HSQL nie może załadować pliku.HSQL DB w Servlet: plik blokady nie został zwolniony

Web serwer Tomcat 7.0.22 dostarczany z NetBeans ...

pomysłów, dlaczego tak się dzieje?

Oto kod startowych:

@Override 
public void destroy() { 
    super.destroy(); 
    server.setNoSystemExit(true); 
    server.stop(); 
    server.shutdown(); 
    controller.shutdown(); 
} 

używam WZP:

@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 */ 
    } 

Oto moja metoda zamykania/zniszczyć. Jeśli baza danych zostanie załadowana (pierwsze uruchomienie), aplikacja działa poprawnie. Oto moja 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> 

dodałem „hsqldb.lock_file = false” dla celów testowych, która nie ma wpływu w ogóle. Ogólnie nie chcę wyłączać blokowania plików ...

Dzięki!

Odpowiedz

1

Jeśli chcesz uzyskać dostęp do bazy danych z poziomu samej aplikacji internetowej niż byłoby lepiej:

  1. run HSQLDB w trybie "in-process".
  2. zdefiniuj bazę danych jako Tomcat's resource i uzyskaj dostęp do niej za pomocą JNDI.

To pomogłoby całkowicie pozbyć się obciążenia start/stop hsqldb.

+0

Czy możesz podać mi więcej szczegółów dotyczących tego rozwiązania? Jak wyglądałby mój plik persistence.xml? A jeśli zdefiniuję zasób i muszę określić, gdzie będzie rzeczywisty plik HSQL. Nadal mam problem z dynamicznym ustawianiem ścieżki pliku ... –

+0

Bazy danych HSQLDB przechowywane jako zasoby są tylko do odczytu. Zobacz http://www.hsqldb.org/doc/1.8/src/org/hsqldb/jdbc/jdbcConnection.html –

0

Hi rozwiązać problem w ten sposób:

@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(); 
} 

Moim jedynym problemem jest to, że opuścił rodzimy zapytania SHUTDOWN załatwia sprawę, ale również powoduje wyjątki generowane przez odpowiedni EntityManager. Moja teoria jest taka, że ​​baza danych jest zamknięta i zatrzymał się przed EntityManager zamknął swoje połączenie ...

Gdybym wydrukować ślad stosu z catched Throwable t uzyskać:

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 

Czy wiesz, co jest tego przyczyną wyjątki?