【问题标题】:ORMLite SQLite w/ Plain Java Error: "SQL error or missing database"ORMLite SQLite w/普通 Java 错误:“SQL 错误或缺少数据库”
【发布时间】:2014-02-16 08:58:12
【问题描述】:

几个月来,我在几个不同的项目中一直在 Android 上使用 ORMLite。太棒了!前几天我开始向后移植我的一个项目,该项目有一个普通的旧 java 组件,我解析一些数据,并创建一个包含在 android 项目中的 sqlite 数据库。

我一直在使用 jdbc 库来调用普通的 sqlite 语句,当我使用 xerial 的 jdbc 库切换到 ormlite-jdbc 时,当我尝试在新的数据库文件中创建表时,我的代码立即抛出错误:

Exception in thread "main" com.test.library.java.exception.BAException: java.sql.SQLException: SQL statement failed: CREATE TABLE IF NOT EXISTS `chapter` (`book` VARCHAR NOT NULL , `chapter` INTEGER , `chapter` VARCHAR NOT NULL , `_id` INTEGER PRIMARY KEY AUTOINCREMENT ) 
    at com.test.parser.Database.createTables(Database.java:109)
    at com.test.parser.Database.<init>(Database.java:81)
    at com.test.parser.runnable.TranslationParserRunnable.run(TranslationParserRunnable.java:35)
    at com.test.parser.Parser.parse(Parser.java:13)
    at com.test.parser.Main.main(Main.java:41)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: java.sql.SQLException: SQL statement failed: CREATE TABLE IF NOT EXISTS `chapter` (`book` VARCHAR NOT NULL , `chapter` INTEGER , `chapter` VARCHAR NOT NULL , `_id` INTEGER PRIMARY KEY AUTOINCREMENT ) 
    at com.j256.ormlite.misc.SqlExceptionUtil.create(SqlExceptionUtil.java:22)
    at com.j256.ormlite.table.TableUtils.doStatements(TableUtils.java:468)
    at com.j256.ormlite.table.TableUtils.doCreateTable(TableUtils.java:442)
    at com.j256.ormlite.table.TableUtils.createTable(TableUtils.java:220)
    at com.j256.ormlite.table.TableUtils.createTableIfNotExists(TableUtils.java:61)
    at com.test.parser.Database.createTables(Database.java:102)
    ... 9 more
Caused by: java.sql.SQLException: [SQLITE_ERROR] SQL error or missing database (duplicate column name: chapter)
    at org.sqlite.DB.newSQLException(DB.java:383)
    at org.sqlite.DB.newSQLException(DB.java:387)
    at org.sqlite.DB.throwex(DB.java:374)
    at org.sqlite.NestedDB.prepare(NestedDB.java:134)
    at org.sqlite.DB.prepare(DB.java:123)
    at org.sqlite.PrepStmt.<init>(PrepStmt.java:42)
    at org.sqlite.Conn.prepareStatement(Conn.java:404)
    at org.sqlite.Conn.prepareStatement(Conn.java:399)
    at com.j256.ormlite.jdbc.JdbcDatabaseConnection.compileStatement(JdbcDatabaseConnection.java:131)
    at com.j256.ormlite.table.TableUtils.doStatements(TableUtils.java:459)
    ... 13 more

要得到这个错误,我要做的就是:

public Database(File dbFile) {
    try {
      // load the sqlite-JDBC driver using the current class loader
      Class.forName("org.sqlite.JDBC");
    } catch (ClassNotFoundException e) {
      throw new BAException(e);
    }

    dbFile.getParentFile().mkdirs();
    dbFile.delete();

    String connectionName = "jdbc:sqlite:" + dbFile.getPath();
    System.out.println("Connection Path: " + connectionName);

    try {
      mConnectionSource = new JdbcConnectionSource(connectionName);
      createTables();
    } catch (SQLException e) {
      throw new BAException(e);
    }

    createTables();
  }

  private  void createTables() {
    try {
      TableUtils.createTableIfNotExists(mConnectionSource, ExampleTable.class);
    } catch (SQLException e) {
      throw new BAException(e);
    }

  }

当我尝试创建表时引发错误。有趣的是,如果我直接使用 JDBC,一切正常:

public Database(File dbFile) {
        try {
          // load the sqlite-JDBC driver using the current class loader
          Class.forName("org.sqlite.JDBC");
        } catch (ClassNotFoundException e) {
          throw new BAException(e);
        }

        dbFile.getParentFile().mkdirs();
        dbFile.delete();

        String connectionName = "jdbc:sqlite:" + dbFile.getPath();
        System.out.println("Connection Path: " + connectionName);

try {
  Connection connection = DriverManager.getConnection(connectionName);

  Statement statement = null;
  try {
    statement = connection.createStatement();
    statement.setQueryTimeout(30);

    statement.executeUpdate(SQL.CREATE_TABLE_EXAMPLE);
    statement.executeUpdate("CREATE TABLE \"android_metadata\" (\"locale\" TEXT DEFAULT 'en_US')");
    statement.executeUpdate("INSERT INTO \"android_metadata\" VALUES ('en_US')");
  } catch (SQLException e) {
    e.printStackTrace();
  } finally {
    try {
      if (statement != null)
        statement.close();
    } catch (SQLException e) {
      e.printStackTrace();
    }
  }

} catch (SQLException e) {
  throw new BAException(e);
}

同样,这工作正常,使用 ORMLite 的等效项会引发缺少数据库异常。我花了 6 个多小时试图解决这个问题,似乎问题出在 ormlite 上。我注意到在运行mConnectionSource = new JdbcConnectionSource(connectionName); 时创建了一个空数据库文件(至少我假设这是创建它的行),但是我似乎缺乏与之交互的能力。

我找不到任何使用 DAO 和连接源与 sqlite 交互的 ormlite 代码示例。似乎所有的 jdbc 示例都是使用 h2 内存数据库完成的。

任何帮助都会很棒。

其他一些信息: 我正在用 gradle 构建。

compile 'com.j256.ormlite:ormlite-jdbc:4.48'
compile 'org.xerial:sqlite-jdbc:3.7.2'

【问题讨论】:

  • 这是在安卓上吗?您应该为 ORMLite 使用 Android 后端,而不是 JDBC,对吗?
  • 有关 Sqlite 的示例,您可以查看 ormlite-tests 项目,其中包含需要数据库支持的测试。例如:github.com/j256/ormlite-tests/blob/master/src/test/java/com/…
  • 所以这不是直接在Android上使用的。这被用于创建在 Android 上使用的 sqlite 数据库的 Java 项目中。所以这是纯java。我正在将一个已经工作的 jdbc 项目转换为使用 ormlite。
  • 你能显示正在执行的create table语句吗?
  • 我真的因此而责怪 sqlite。如果他们刚刚遇到“SQL 问题重复列名”,您就不会遇到问题。是“缺少数据库或...”类型的错误消息让您放慢了速度。

标签: java sqlite jdbc ormlite


【解决方案1】:

当我尝试在新的数据库文件中创建表时,我的代码立即抛出错误:

因此,可能的问题可能是您似乎正在尝试写入 目录 而不是数据库文件:

dbFile.mkdirs();
dbFile.delete();
String connectionName = "jdbc:sqlite:" + dbFile.getPath();
...

也许你的意思是:

dbFile.getParentFile().mkdirs();

如果dbFile 应该是一个目录,那么您需要在文件后提供一个名称:

String connectionName = "jdbc:sqlite:" + dbFile.getPath() + "/db.sqlite";

【讨论】:

  • 数据库文件正在创建中。我可以在文件系统中看到数据库
  • 所以我猜它可以工作,因为您正在创建目录(和父目录),然后删除目录,然后将其创建为文件。我会至少更改mkDirs() 行@spierce7。
  • 当我只使用普通 JDBC 时,完全相同的代码可以正常工作。我提供了两个例子。在 JDBC 示例之后,我可以使用 sqlite 浏览器打开文件并查看它。 ORMLite 示例并非如此。我会根据您的建议进行更改,(实际上我在测试中已经尝试过),但问题似乎出在 ORMLite 的实际使用中。我很困惑。
  • 试过了。编辑原始问题以符合您的建议。仍然收到错误。还添加了完整的堆栈跟踪。 dbFile 在路径中有文件名。
【解决方案2】:

我有 2 列同名。修复后,一切正常。 ORMLite 很棒。

【讨论】:

    猜你喜欢
    • 2014-06-03
    • 2011-01-28
    • 1970-01-01
    • 1970-01-01
    • 2020-12-11
    • 1970-01-01
    • 2017-10-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多