Spring Boot App - Tomcat 无法访问 SQLite 数据库文件

Posted

技术标签:

【中文标题】Spring Boot App - Tomcat 无法访问 SQLite 数据库文件【英文标题】:Spring Boot App - Tomcat can't access SQLite database file 【发布时间】:2021-09-19 17:04:41 【问题描述】:

我这几天一直在寻找这个解决方案,但我找不到解决方案。

我有一个应该与数据库交互的 Java Spring Boot 应用程序,为了便于使用和存储,我选择了一个 SQLite 数据库文件。我的应用程序托管在 Windows Server 2019 上的 Tomcat 8.5 上。

在启动时,我的应用程序应该读取 SQLite 数据库,但出现错误:[SQLITE_ERROR] SQL error or missing database (no such table: users_moved_group)

错误表明应用程序找不到数据库但它确实存在,我已经仔细检查了一千次路径(我也尝试了绝对和相对路径),这里是:

spring.datasource.url = jdbc:sqlite:C:/Tomcat 8.5/db/workday.sqlite

如您所见,一切正常。所以我的猜测是 Tomcat 服务无法读取该文件,但它位于 Tomcat 文件夹内,尤其是为了避免这种错误(在全新安装 Windows Server 和 Tomcat 时它可以工作)。

这个问题只发生在 3 个虚拟机之一上,不是我的,但我仍然拥有几乎所有的管理员权限。

我完全迷失了,我没有做任何事情让 Tomcat 看到文件以允许我的应用程序读取它。

这是读取数据库的示例代码:

public void clearTable()

Connection connection;
String usersMovedGroupTable = "users_moved_group";
String sqlExpression = "SELECT * FROM " + usersMovedGroupTable;

List<UsersMovedGroup> usersMovedGroupList = new ArrayList<>();

try 
    connection = DriverManager.getConnection(applicationProperties.getDatasourceUrl());
    Statement statement = connection.createStatement();

    ResultSet rs = statement.executeQuery(sqlExpression);
    while(rs.next())
    
        UsersMovedGroup user = new UsersMovedGroup(rs.getString("ump_date"), rs.getString("ump_user_id"), rs.getString("ump_user_login"), rs.getString("ump_group_id"), rs.getString("ump_group_name"));
        usersMovedGroupList.add(user);
    
 catch (SQLException e) 
    logger.error("Error connecting to SQLite database : " + e.getMessage());

起初我使用jdbcTemplate 发出SQL 请求,但我将其更改为Statement 等,但结果相同。

如果你想要这里是我的 pom.xml :

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.4.4</version>
    <relativePath/>
  </parent>

  <groupId>com.sqlite</groupId>
  <artifactId>user-moved-ad-group-event-hook</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>
  <name>user-moved-ad-group-event-hook</name>
  <description>Detect user changed of AD group</description>

  <properties>
    <java.version>1.8</java.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
    
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-lang3</artifactId>
      <version>3.5</version>
    </dependency>

    <!-- SQLite -->
    <dependency>
      <groupId>org.xerial</groupId>
      <artifactId>sqlite-jdbc</artifactId>
      <version>3.34.0</version>
    </dependency>

    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.17</version>
      <scope>compile</scope>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-jdbc</artifactId>
      <version>RELEASE</version>
    </dependency>

    <dependency>
      <groupId>org.thymeleaf</groupId>
      <artifactId>thymeleaf-spring5</artifactId>
    </dependency>
  </dependencies>

  <build>
    <finalName>$project.artifactId</finalName>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <version>2.4.4</version>
      </plugin>
    </plugins>
  </build>

  <profiles>
    <profile>
      <id>dev</id>
      <activation>
        <activeByDefault>true</activeByDefault>
      </activation>
      <properties>
        <activatedProperties>dev</activatedProperties>
      </properties>
    </profile>
    <profile>
      <id>lyvoc</id>
      <properties>
        <activatedProperties>lyvoc</activatedProperties>
      </properties>
    </profile>
    <profile>
      <id>prod</id>
      <properties>
        <activatedProperties>prod</activatedProperties>
      </properties>
    </profile>
  </profiles>

</project>

【问题讨论】:

为什么不先测试一下你的理论,看看你是否可以在文件 C:/Tomcat 8.5/db/workday.sqlite 上打开一个流,然后再做任何其他事情。 "no such table: users_moved_group":我相信这是错误的原因。与数据库的连接应该没问题。 BTW:你的代码没有使用 Spring 的数据源,而是建立了独立的连接。 @g00se 似乎new BufferedReader(new FileReader("linxensworkday.sqlite") 发现我的文件作为日志记录buffer.readLine() 给了我这个SQLite format 3 @ .K�。所以我不明白为什么connection 不起作用。 @Piotr P. Karwasz 正如我所说,我在开始使用 JdbcTemplate 时使用的是 Spring 数据源,但同样的事情发生的不太清楚 分享指向该数据库文件的链接? 我建议将文件移动到类路径内的文件夹中。 【参考方案1】:

你试过 usersMovedGroupTable = "Schema_Name.DataBase_Name";

【讨论】:

嗨@Akin,请使用 cmets 部分澄清您对已发布问题的所有未决查询。如果您对问题有任何建议,请使用答案部分。 @Akin 我不明白你的评论,这个变量是我的sqlite数据库“workday.sqlite”中包含的表“users_moved_group”的名称 @JérémiePoisson 有时 sql 无法找到只有表名的表,因为在不同的 shcema 中可能有多个同名的表,那么我们需要向 SQL 显示我们需要使用哪个 shcema,例如 [schema_name].table_name 【参考方案2】:

回来提供一些反馈。在尝试了一切之后,我尝试全新安装 Tomcat 9.0(而不是常用的 8.5),现在一切正常,代码没有任何变化。

【讨论】:

以上是关于Spring Boot App - Tomcat 无法访问 SQLite 数据库文件的主要内容,如果未能解决你的问题,请参考以下文章

无法在 Eclipse 中启动 Spring Boot App:无法启动嵌入式 Tomcat

将 Spring Boot 部署到 Tomcat

Spring MVC或Spring Boot配置默认访问页面不生效?

如何在 Spring Boot 2.0 上将默认 hikari cp 替换为 tomcat 池

如何持久化在 docker 内的 tomcat 上运行的 Spring Boot 应用程序的会话

Spring Boot 和 Nginx 集成