我在幾個不同的項目中在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'
這是在Android上?你應該爲ORMLite使用Android後端,而不是JDBC,對吧? – Gray
對於Sqlite的示例,您可以查看具有需要數據庫支持的測試的ormlite-tests項目。例如:https://github.com/j256/ormlite-tests/blob/master/src/test/java/com/j256/ormlite/db/SqliteConnectTest.java – Gray
所以這不是直接在Android上使用。這被用在一個Java項目中,該項目創建了一個在Android上使用的sqlite數據庫。所以這是純java。我將一個已經工作的jdbc項目轉換爲使用ormlite。 – spierce7