2014-02-16 3 views
0

Я использую 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' 
+0

Это на Android? Вы должны использовать бэкэнд для Android для ORMLite и _not_ 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-проекте, который создает базу данных sqlite, которая используется на Android. Так что это чистый 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

Так что я думаю, это работает, потому что вы создаете каталог (и родительский), а затем удаляете каталог и затем создаете его в виде файла. Я бы изменил эту строку 'mkDirs()' как минимум @ spierce7. – Gray

+0

Точно такой же код работает A-OK, когда я просто использую простой JDBC. Я представил оба примера. После примера JDBC я могу открыть файл с помощью браузера sqlite и просматривать его просто отлично. Не так с примером ORMLite. Я сделаю ваши предложенные изменения (я на самом деле пробовал это в своем тестировании), но проблема, похоже, заключается в фактическом использовании ORMLite. Я довольно тупой. – spierce7

Смежные вопросы