2014-02-16 58 views
0

我在幾個不同的項目中在Android上使用ORMLite數月。太棒了!有一天,我開始回溯我的一個項目,該項目有一個簡單的舊Java組件,我解析了一些數據,並創建了一個包含在android項目中的sqlite數據庫。帶有普通Java的ORMLite SQLite錯誤:「SQL錯誤或缺少數據庫」

我一直在使用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' 
+0

這是在Android上?你應該爲ORMLite使用Android後端,而不是JDBC,對吧? – Gray

+0

對於Sqlite的示例,您可以查看具有需要數據庫支持的測試的ormlite-tests項目。例如:https://github.com/j256/ormlite-tests/blob/master/src/test/java/com/j256/ormlite/db/SqliteConnectTest.java – Gray

+1

所以這不是直接在Android上使用。這被用在一個Java項目中,該項目創建了一個在Android上使用的sqlite數據庫。所以這是純java。我將一個已經工作的jdbc項目轉換爲使用ormlite。 – spierce7

回答

1

我有2個同名的列。解決之後,一切正常。 ORMLite是美好的。

1

immediately my code throws an error when I try to create a table in a fresh database file:

因此,對可能出現的問題可能是你似乎在試圖寫一個目錄而不是數據庫文件:

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

也許你的意思是:

dbFile.getParentFile().mkdirs(); 

如果dbFile應該是一個目錄然後你需要在文件後面提供一個名字:

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

正在創建數據庫文件。我可以在文件系統中看到數據庫 – spierce7

+0

所以我猜測它是有效的,因爲您正在創建目錄(和父目錄),然後刪除該目錄,然後將其創建爲文件。至少@ spierce7我會改變'mkDirs()'行。 – Gray

+0

完全相同的代碼工作A - 確定,當我只使用普通的JDBC。我提供了兩個例子。在JDBC示例之後,我可以用sqlite瀏覽器打開文件並查看它。 ORMLite的例子並非如此。我會提出你的建議修改,(我實際上已經在我的測試中試過了),但問題似乎是ORMLite的實際使用。我很難過。 – spierce7

相關問題