2015-12-20 88 views
5

Używam UCanAccess do manipulowania bazą danych Access. Podczas wywoływania executeUpdate uzyskać wyjątek:Wyjątek UCanAccess/Jackcess podczas wywoływania executeUpdate wyłącza moje wyjście Logger

net.ucanaccess.jdbc.UcanaccessSQLException: UCAExc ::: 3.0.2 Nieoczekiwany typ strona 1 (DB = db.accdb; Tabela = MOJA_TABELA; X = primaryKey)

Występuje tylko podczas próby aktualizacji określonego wiersza - już wiem, jak to naprawić w Access DB.

Problem dotyczy rejestratora, po wygenerowaniu tego wyjątku i przechwyceniu go, loguję komunikat informacyjny i nie jest wyświetlany, wszystkie następne komunikaty dziennika nie są wyświetlane.

Powodem, dla którego chcę to naprawić bez naprawy DB, jest fakt, że gdy wystąpi raz, użytkownik powinien zamknąć aplikację w celu zarejestrowania kolejnych działań, jeśli tego nie zrobi, nie będę mógł się dowiedzieć co on zrobił.

To jest mój kod:

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"); 
    } 
} 

Wyjście konsola jest:

net.ucanaccess.jdbc.UcanaccessSQLException: UCAExc ::: 3.0.2 Nieoczekiwany typ strona 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) w sieci .ucanaccess.jdbc.UcanaccessConnection.commit (Ucanacce ssConnection.java:205) w net.ucanaccess.jdbc.AbstractExecute.executeBase (AbstractExecute.java:161) w net.ucanaccess.jdbc.ExecuteUpdate.execute (ExecuteUpdate.java:50) w net.ucanaccess.jdbc. UcanaccessPreparedStatement.executeUpdate (UcanaccessPreparedStatement.java:253) at rashi.NewClass.main (NewClass.java:61) Wywołane przez: java.io.IOException: Nieoczekiwany typ strony 1 (Db = db.accdb; Table = myTable; Indeks = PrimaryKey) w com.healthmarketscience.jackcess.impl.IndexData.isLeafPage (IndexData.java:1185) w com.healthmarketscience.jackcess.impl.IndexData.readDataPage (IndexData.java:1067) w com.healthmarketscience.jackcess .impl.IndexPageCache.readDataPage (IndexPageCache.java:267) na com.healthmarketscience.jac kcess.impl.IndexPageCache.getDataPage (IndexPageCache.java:224) na com.healthmarketscience.jackcess.impl.IndexPageCache.getCacheDataPage (IndexPageCache.java:211) ..............

INSIDE Wyjątek

A mój plik dziennika zawiera tylko ten wiersz:

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

co oznacza moja rejestrator nie jest już aktywna. Sądzę, że niektóre zmiany rejestratora przed wyjątkiem w UCanAccess.

+0

W aktualnej programu jest rejestrator static final taki sposób, że nie mogą być zbierane śmieci? – jmehrens

+0

mój aktualny program zawiera statyczny rejestrator końcowy. Utworzyłem dostęp do pliku db z tym wyjątkiem, załaduję go później. Tymczasem wszelkie sugestie dotyczące korzystania z innej kompaktowej bazy danych, które nie będą wymagały dużych zmian w kodzie? Nie chcę, aby te błędy pojawiały się, gdy aplikacja jest w fazie produkcji (ponieważ próbowałem "kompaktować i naprawiać", a wiele wierszy zostało usuniętych). –

+0

Udało mi się utworzyć (uszkodzony) plik .mdb, który odtwarza twój problem i zgłosił go do zespołu programistycznego UCanAccess. –

Odpowiedz

1

Wygląda na efekt uboczny HSQLDB, który występuje, gdy UCanAccess wykonuje fizyczne wycofywanie i wyłącza kopię lustrzaną.

Ustawienie właściwości systemu hsqldb.reconfig_logging na false może rozwiązać problem, np.,

-Dhsqldb.reconfig_logging=false 

lub

System.setProperty("hsqldb.reconfig_logging", "false"); 
+0

System.setProperty ("hsqldb.reconfig_logging", "false"); rozwiązał mój problem. kiedy ustawię tę właściwość, mój program rejestrujący kontynuuje zapisywanie swoich wiadomości. Dzięki! –

+0

Mogę ustawić to jako domyślne, ale przede wszystkim chcę mieć pewność, że nie doprowadzi to do jakiegoś efektu ubocznego. – jamadei