leinn32 / h2database

Automatically exported from code.google.com/p/h2database
0 stars 0 forks source link

[MVStore] org.h2.mvstore.db.MVTable throws java.lang.NullPointerException #464

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
H2 Version: svn trunk

Test:
==========================================
Issue 458 : java.sql.Connection.setAutoCommit(false) & Savepoint do not work
https://code.google.com/p/h2database/issues/detail?id=458

Run:
===============
The first Run is OK,
but the second Run throws a java.lang.NullPointerException

Exception Stacktrace:
===============
org.h2.jdbc.JdbcSQLException: General error: "java.lang.NullPointerException" 
[50000-171]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:329)
    at org.h2.message.DbException.get(DbException.java:158)
    at org.h2.message.DbException.convert(DbException.java:281)
    at org.h2.server.TcpServerThread.sendError(TcpServerThread.java:213)
    at org.h2.server.TcpServerThread.run(TcpServerThread.java:153)
    at java.lang.Thread.run(Thread.java:662)
Caused by: java.lang.NullPointerException
    at org.h2.mvstore.db.MVTable.getMapName(MVTable.java:100)
    at org.h2.engine.Session.rollbackTo(Session.java:563)
    at org.h2.command.Command.executeUpdate(Command.java:258)
    at org.h2.server.TcpServerThread.process(TcpServerThread.java:335)
    at org.h2.server.TcpServerThread.run(TcpServerThread.java:151)
    ... 1 more

    at org.h2.engine.SessionRemote.done(SessionRemote.java:578)
    at org.h2.command.CommandRemote.executeUpdate(CommandRemote.java:186)
    at org.h2.jdbc.JdbcSavepoint.rollback(JdbcSavepoint.java:66)
    at org.h2.jdbc.JdbcConnection.rollback(JdbcConnection.java:995)
    at my.test.mvstore.TransactionTest.run(TransactionTest.java:66)
    at my.test.mvstore.TransactionTest.testMVTable(TransactionTest.java:40)

Analyze:
===============
1. The MVTable.removeChildrenAndResources method is called when executes the 
SQL "DROP TABLE IF EXISTS TransactionTest"

2. The primaryIndex field is set to null

3. The old MVTable instance is not deleted from the 
MVTableEngine.Store.openTables

4. When traverse the elements in the MVTableEngine.Store.openTables like this:
            //org.h2.engine.Session.rollbackTo(Savepoint, boolean)
            for (MVTable t : database.getMvStore().getTables()) {
                if (changed.contains(t.getMapName())) {
                    t.setModified();
                }
            }
   In the step 2, the primaryIndex field is set to null, so t.getMapName() will throw a NullPointerException

Fix:
===============

Currently,the MVTable.close(Session) method does not do anything,
therefore, remove the old MVTable instance here is very suitable, as following:
    @Override
    public void close(Session session) {
        session.getDatabase().getMvStore().getTables().remove(this);
    }
In addition, also need to consider concurrency issues-related to the 
MVTableEngine.Store.openTables

Original issue reported on code.google.com by zhh200...@gmail.com on 18 May 2013 at 3:53

GoogleCodeExporter commented 9 years ago
Fixed in revision 4806, test case TestMVTableEngine.testAutoCommit().

Thanks for reporting the issue!

Original comment by thomas.t...@gmail.com on 19 May 2013 at 12:45

GoogleCodeExporter commented 9 years ago
Fixed in version 1.3.172.

Original comment by thomas.t...@gmail.com on 25 May 2013 at 1:49