Jersey 和 Hibernate 的数据库锁获取失败

DB lock acquisition failure with Jersey and Hibernate

我在远程服务器 运行 linux 上设置项目时遇到问题。它在 Windows.

上本地运行良好

我的应用程序在 Jersey、Hibernate 和文件 HSQLDB 上 运行。我正在使用 maven tomcat 插件在本地开发它并部署到我的远程 VPS。在本地我使用 mvn tomcat7:run,部署我使用 mvn tomcat7:redeploy.

这是我的休眠配置:

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <!-- Database connection settings -->
        <property name="connection.driver_class">org.hsqldb.jdbcDriver</property>
        <property name="connection.url">jdbc:hsqldb:file:data/HDB</property>
        <property name="connection.username">sa</property>
        <property name="connection.password"></property>

        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">1</property>

        <!-- SQL dialect -->
        <property name="dialect">org.hibernate.dialect.HSQLDialect</property>

        <!-- Enable Hibernate's automatic session context management -->
        <property name="current_session_context_class">thread</property>
        <property name="transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>

        <property name="show_sql">true</property>

        <property name="hbm2ddl.auto">update</property>

        <mapping class="com.example.MyClass" />
    </session-factory>
</hibernate-configuration>

它在本地工作得很好,在启动时它会在项目根目录中创建 data 文件夹并在那里存储数据库文件,效果很好。但是当我将它部署到远程服务器时 Tomcat 抛出这个异常:

Caused by: org.hsqldb.HsqlException: Database lock acquisition failure: lockFile: org.hsqldb.persist.LockFile@803b3767[file =/data/HDB.lck, exists=false, locked=false, valid=false, ] method: openRAF reason: java.io.FileNotFoundException: /data/HDB.lck (No such file or directory)
        at org.hsqldb.error.Error.error(Unknown Source)
        at org.hsqldb.error.Error.error(Unknown Source)
        at org.hsqldb.persist.LockFile.newLockFileLock(Unknown Source)
        at org.hsqldb.persist.Logger.acquireLock(Unknown Source)
        at org.hsqldb.persist.Logger.open(Unknown Source)
        at org.hsqldb.Database.reopen(Unknown Source)
        at org.hsqldb.Database.open(Unknown Source)
        at org.hsqldb.DatabaseManager.getDatabase(Unknown Source)
        at org.hsqldb.DatabaseManager.newSession(Unknown Source)
        ... 74 more

这不会让我的应用程序启动。它在 myapp/WEB-INF/lib 中创建 data 文件夹并将 HDB 文件放在那里,但它看起来无法连接到数据库。请注意 file =/data/HDB.lck 表示绝对路径 - 这是此错误的原因吗?为什么 Tomcat on Linux 在路径前添加这个斜杠?如何摆脱它?为什么同样适用于 Windows?

另外web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0">
    <display-name>My server</display-name>

    <filter>
        <filter-name>jersey</filter-name>
        <filter-class>com.sun.jersey.spi.container.servlet.ServletContainer</filter-class>

        <init-param>
            <param-name>com.sun.jersey.config.property.packages</param-name>
            <param-value>com.example.rest</param-value>
        </init-param>

        <init-param>
            <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
            <param-value>true</param-value>
        </init-param>

    </filter>

    <filter-mapping>
        <filter-name>jersey</filter-name>
        <url-pattern>/api/*</url-pattern>
    </filter-mapping>

    <listener>
        <listener-class>com.example.HibernateListener</listener-class>
    </listener>

    <welcome-file-list>
        <welcome-file>gui.html</welcome-file>
    </welcome-file-list>
</web-app>

还有 HibernateListener 因为它被引用 - 它用于在部署后立即设置数据库连接:

public class HibernateListener implements ServletContextListener {

    public void contextInitialized(ServletContextEvent event) {
        Db.getSessionFactory();
    }

    public void contextDestroyed(ServletContextEvent event) {
        Db.getSessionFactory().close();
    }
}

看起来文件夹是 read-only。

您可以使用在 Tomcat 属性中定义的变量作为数据库路径的一部分,以指定不同的文件夹。例如

  <property name="connection.url">jdbc:hsqldb:file:${mydbpath}/data/HDB</property>