Hello!
I ran into a problem trying to use SQLite with spring. I use SQLite in-memory database, and - since every connection to "jdbc:sqlite::memory:" creates a new database, I need a single connection in the application, so I use SingleConnectionDataSource.
The problem happens, when I use a SimpleJdbcInsert. When I call executeAndReturnKey, I got a NullpointerException:
I made a class to demonstrate the problem:Code:Exception in thread "main" java.lang.NullPointerException at org.springframework.jdbc.core.metadata.GenericTableMetaDataProvider.locateTableAndProcessMetaData(GenericTableMetaDataProvider.java:304) at org.springframework.jdbc.core.metadata.GenericTableMetaDataProvider.initializeWithTableColumnMetaData(GenericTableMetaDataProvider.java:216) at org.springframework.jdbc.core.metadata.TableMetaDataProviderFactory$1.processMetaData(TableMetaDataProviderFactory.java:94) at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:290) at org.springframework.jdbc.core.metadata.TableMetaDataProviderFactory.createMetaDataProvider(TableMetaDataProviderFactory.java:63) at org.springframework.jdbc.core.metadata.TableMetaDataContext.processMetaData(TableMetaDataContext.java:205) at org.springframework.jdbc.core.simple.AbstractJdbcInsert.compileInternal(AbstractJdbcInsert.java:280) at org.springframework.jdbc.core.simple.AbstractJdbcInsert.compile(AbstractJdbcInsert.java:265) at org.springframework.jdbc.core.simple.AbstractJdbcInsert.checkCompiled(AbstractJdbcInsert.java:316) at org.springframework.jdbc.core.simple.AbstractJdbcInsert.doExecuteAndReturnKey(AbstractJdbcInsert.java:391) at org.springframework.jdbc.core.simple.SimpleJdbcInsert.executeAndReturnKey(SimpleJdbcInsert.java:126) at InsertBug.main(InsertBug.java:31)
The problem is that in the GenericTableMetaDataProvider class, the username instance variable has a value of null. That's probably because SQLite does not have an authentication mechanism. Therefore the userName.toUpperCase() call will throw a NullpointerException at line 304.Code:import javax.sql.DataSource; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.simple.SimpleJdbcInsert; import org.springframework.jdbc.datasource.SingleConnectionDataSource; public class InsertBug { /** * @param args * @throws ClassNotFoundException */ public static void main(String[] args) throws ClassNotFoundException { if (args.length != 1) { System.out.println("database file path needs to be specified"); return; } Class.forName("org.sqlite.JDBC"); DataSource dataSource = new SingleConnectionDataSource("jdbc:sqlite:" + args[0], true); SimpleJdbcInsert insert = new SimpleJdbcInsert(dataSource); insert.withTableName("Graph").usingGeneratedKeyColumns("GId"); MapSqlParameterSource params = new MapSqlParameterSource(); params.addValue("Level", 1); int id = insert.executeAndReturnKey(params).intValue(); System.out.println("Returned key: " + Integer.toString(id)); } }
I use Spring 3.0.5. The example code uses a file based database instead the in-memory I mentioned earlier, but I use that only to have a table up and runnning for the test.


Reply With Quote
