Я использую ORMLite в течение нескольких месяцев на Android в нескольких разных проектах. Это было здорово! На днях я начал backporting мой проект, который имеет простой старый компонент java, который я разбираю некоторые данные и создаю базу данных sqlite, которую я включаю в проект Android.ORMLite SQLite w/Plain Java Error: «Ошибка SQL или отсутствующая база данных»
Я использовал библиотеку jdbc для вызова простых операторов sqlite, а когда я перешел на ormlite-jdbc с библиотекой jdbc от xerial, сразу же мой код выдает ошибку при попытке создать таблицу в новом файле базы данных:
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);
создается пустой файл базы данных (по крайней мере, я предполагаю, что это строка, которая его создает), но тогда мне, похоже, не хватает возможности взаимодействовать с ним.
Я не смог найти какие-либо примеры ormlite-кода, взаимодействующие с sqlite, используя источники DAO и соединения. Кажется, все примеры jdbc выполнены с использованием базы данных h2.
Любая помощь будет замечательной.
Дополнительная информация: Я строию град.
compile 'com.j256.ormlite:ormlite-jdbc:4.48'
compile 'org.xerial:sqlite-jdbc:3.7.2'
Это на Android? Вы должны использовать бэкэнд для Android для ORMLite и _not_ 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-проекте, который создает базу данных sqlite, которая используется на Android. Так что это чистый java. Я конвертирую уже работающий проект jdbc для использования ormlite. – spierce7