5

I am using UCanAccess for manipulating an Access database. When calling executeUpdate I get the exception:

net.ucanaccess.jdbc.UcanaccessSQLException: UCAExc:::3.0.2 Unexpected page type 1 (Db=db.accdb;Table=MyTable;Index=PrimaryKey)

It only occurs when trying to update one specific row - I already know how to fix this in the Access DB.

The problem is with the Logger, after this exception is thrown and I catch it, I log an info message and it is not shown, all of the next log messages are not shown either.

The reason why I want to fix it without fixing the DB is because when it occurs once, the user should close the application in order to log the next actions, if he doesn't then I will not be able to know what he did.

This is my code:

public static void main(String args[]) {
    Logger logger = Logger.getLogger("myLogger");
    PreparedStatement pst = null;
    try {
        FileHandler fileHandler = new FileHandler("myLog.log", 0, 1, true);

        // Set formatter to put the time, the message, and the exception if exists
        fileHandler.setFormatter(new Formatter() {
            @Override
            public String format(LogRecord record) {
                Throwable t = record.getThrown();
                String stackTrace = "";
                if (t != null) {
                    StringWriter sw = new StringWriter();
                    t.printStackTrace(new PrintWriter(sw));
                    stackTrace = sw.toString();
                }

                return  Calendar.getInstance().getTime() + "--" +
                        formatMessage(record) + stackTrace + "\n";
            }
        });

        // Set the logger handler
        logger.addHandler(fileHandler); 
        logger.log(Level.INFO, "1");

        // Throw on purpose
        String query = "UPDATE myTable SET name = 'a' WHERE id = 289";

        conn = DriverManager.getConnection(DB_URL);
        pst = conn.prepareStatement(query);
        pst.executeUpdate();

        logger.log(Level.INFO, "2");
    } catch (UcanaccessSQLException e) {
        logger.log(Level.INFO, "3");
        System.out.println("INSIDE Exception");
    } catch (SQLException e) {
        logger.log(Level.INFO, "4");
    } catch (Exception e) {
        logger.log(Level.INFO, "5");
    }
}

The console output is:

net.ucanaccess.jdbc.UcanaccessSQLException: UCAExc:::3.0.2 Unexpected page type 1 (Db=db.accdb;Table=myTable;Index=PrimaryKey) at net.ucanaccess.commands.CompositeCommand.persist(CompositeCommand.java:95) at net.ucanaccess.jdbc.UcanaccessConnection.flushIO(UcanaccessConnection.java:315) at net.ucanaccess.jdbc.UcanaccessConnection.commit(UcanaccessConnection.java:205) at net.ucanaccess.jdbc.AbstractExecute.executeBase(AbstractExecute.java:161) at net.ucanaccess.jdbc.ExecuteUpdate.execute(ExecuteUpdate.java:50) at net.ucanaccess.jdbc.UcanaccessPreparedStatement.executeUpdate(UcanaccessPreparedStatement.java:253) at rashi.NewClass.main(NewClass.java:61) Caused by: java.io.IOException: Unexpected page type 1 (Db=db.accdb;Table=myTable;Index=PrimaryKey) at com.healthmarketscience.jackcess.impl.IndexData.isLeafPage(IndexData.java:1185) at com.healthmarketscience.jackcess.impl.IndexData.readDataPage(IndexData.java:1067) at com.healthmarketscience.jackcess.impl.IndexPageCache.readDataPage(IndexPageCache.java:267) at com.healthmarketscience.jackcess.impl.IndexPageCache.getDataPage(IndexPageCache.java:224) at com.healthmarketscience.jackcess.impl.IndexPageCache.getCacheDataPage(IndexPageCache.java:211) ..............

INSIDE Exception

And my log file contains only this row:

Sun Dec 20 15:35:40 IST 2015--1

which means my logger is no longer active. I guess there are some logger changes before the exception in UCanAccess.

Gord Thompson
  • 98,607
  • 26
  • 164
  • 342
EH Sports
  • 63
  • 6
  • In your actual program, is the logger declared static final such that it can not be garbage collected? – jmehrens Dec 20 '15 at 14:34
  • my actual program contain static final logger. I created access db file with that exception, I will upload it later. Meanwhile, any suggestions for using another compact database, that will not require big changes in the code? I don't want these errors to come when application is in production (since I tried to "compact and repair" and a lot of rows have been deleted). – EH Sports Dec 22 '15 at 08:28
  • I managed to create a (damaged) .mdb file that recreates your issue and have reported it to the UCanAccess development team. – Gord Thompson Dec 22 '15 at 11:38
  • Wow thanks! Hope some solution will come from their side. – EH Sports Dec 22 '15 at 13:48

1 Answers1

1

It looks like an HSQLDB side-effect that happens while UCanAccess is doing a physical rollback and shutting down the mirror db.

Setting the system property hsqldb.reconfig_logging to false may solve the issue, e.g.,

-Dhsqldb.reconfig_logging=false

or

System.setProperty("hsqldb.reconfig_logging", "false");
Gord Thompson
  • 98,607
  • 26
  • 164
  • 342
jamadei
  • 1,680
  • 8
  • 8
  • System.setProperty("hsqldb.reconfig_logging", "false"); did solve my problem. when I set this property, my logger continues to write its messages. Thanks! – EH Sports Jan 07 '16 at 06:57
  • I might set this as default, but before all I want to be sure it won't lead to some side effect . – jamadei Jan 07 '16 at 07:16