SQLite exception on Windows and not Mac OSX
-
12-06-2021 - |
Question
I'm developing from Mac OS X a java application that uses a SQLite database using JDBC driver.
The code works perfectly fine on the mac, but I can't use batch inserts using PreparedStatement
s on my Windows box.
EDIT: this also doesn't work with simple Statement
s that contains a single INSERT INTO
instructions (CREATE TABLE
works fine).
My code is basically:
Table creation:
final String sql = "CREATE VIRTUAL TABLE " + TABLE_NAME + " USING fts3("
+ KEY_NOM + ", "
+ KEY_PRENOM + ", "
+ KEY_ADRESSE + ", "
+ KEY_ADRESSE2 + ", "
+ KEY_ADRESSE3 + ");";
try {
final Statement s = mConnection.createStatement();
s.execute(sql);
} catch (final SQLException e) {
L.e("Unable to create table: "+sql+"! "+e);
}
PreparedStatement
creation:
String sql =
"INSERT INTO "+TABLE_NAME
+" ("
+ KEY_NOM + ", "
+ KEY_PRENOM + ", "
+ KEY_ADRESSE + ", "
+ KEY_ADRESSE2 + ", "
+ KEY_ADRESSE3 + ") "
+ " VALUES (?, ?, ?, ?, ?)";
mConnection.setAutoCommit(false);
final PreparedStatement prep = mConnection.prepareStatement(sql);
Then there is a loop that parses a CSV file, and at each line the following code is called:
int i = 1;
prep.setString(i++, ""+lawyer.nom);
prep.setString(i++, ""+lawyer.prenom);
prep.setString(i++, ""+lawyer.adresse);
prep.setString(i++, ""+lawyer.adresse2);
prep.setString(i++, ""+lawyer.adresse3);
prep.addBatch();
When the parsing of the CSV file is over, the following is executed:
final int[] res = prep.executeBatch();
mConnection.setAutoCommit(true);
for (int r: res) {
if (r != 1) {
L.e("Error adding entry!");
}
}
When I call mConnection.setAutoCommit(true);
, the INSERT
s statements are executed when it raises the following exception:
java.sql.SQLException: SQL logic error or missing database
at org.sqlite.DB.throwex(DB.java:288)
at org.sqlite.DB.exec(DB.java:68)
at org.sqlite.Conn.setAutoCommit(Conn.java:166)
Tested environments:
- MacBookAir - Mac OS 10.6 - x64 - Java 1.6.31 - works fine (my development station)
- Laptop - Windows 7 - x64 - Java 1.6.30 - works fine
- MacBook - Mac OS 10.5 - x64 - Java 1.6.26 - works fine
- Desktop - Windows Vista - x86 - Java 1.? - doesn't work
- Server - Windows Server 2003 - unknown arch, x86 guessed - Java 1.7 - doesn't work
- Desktop - Windows Seven - x86 - Java 1.7 - doesn't work
- Desktop - Windows XP - x86 - Java 1.6.31 - doesn't work
It seems that only x64 hosts can make this to work. The following jars are used:
- swt : included the x64 version on x64 hosts, and x86 version on x86 hosts
- sqlitejdbc-v056: apparently this is x86 and x64 compatible
- opencsv: this doesn't contain native code
- iText-2.1.7 and iTextRTF: this doesn't contain native code
So maybe the JDBC SQLite driver isn't fully x86-compatible. I'll try to investigate more.
Solution
TL;DR:
my SQLite JDBC driver was using native code and was not fully compatible with 32 bits processors.
Two possible fixes:
- Use Xerial, a native SQLite JDBC driver that works fine on both Mac OS X 64 bits and Windows 32 bits
- Use a pure java implementation fixed the issue, at the cost of performance.
Explanation:
I've spent the past 3 days banging my head to the wall with an SQLite exception saying "SQL logic error or missing database". I won't comment on the exception text that includes two possible, different errors without saying which could be the cause. I won't comment either on the fact that none of the two errors mentioned in the exception text was the cause of the issue.
Facts:
- SQLite exception stating "SQL logic error or missing database"
- Using jsqlitejdbc v056
- The driver is able to create tables
- The driver is able to select information from tables
- The database file is not corrupted, ie. it is possible to open it with a sqlite client and insert data to the tables
- The driver is unable to insert data into tables
What solved my issue is replace sqlitejdbc-v056.jar
which contains native code by sqlitejdbc-v056-pure.jar
which is a pure-java implementation.
I hope that all the users that had this issue will be able to quickly see this, and not lose 3 days on this.