'How do I get H2 database trigger to work in server mode?

I am an inexperienced H2 Trigger developer... So lets get that out of the way (ie I am dumb)... Plus, I am reluctant to even ask questions here since it seems that there is an abundance of mean people.

What I am trying to do: Create a Trigger for updates to a row on one table (ie TEST) and log the original row to another table (ie TEST_hist). Additionally, there is some logic if the update is a "delete", then I log the delete with the user name to the history table. I realize what I have done here probably is not good style, but it is just a test and I don't believe that has anything to do with the problem that I am experiencing.

What I have done:

  1. Create a trigger named TriggerTest defined as follows:

    package com.test;

    import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Timestamp;

    import org.h2.api.Trigger;

    public class TriggerTest implements Trigger {

     @Override
     public void init(Connection conn, String schemaName, String triggerName, String tableName, boolean before, int type)
             throws SQLException {
         // TODO Auto-generated method stub
    
     }
    
     @Override
     public void fire(Connection conn, Object[] oldRow, Object[] newRow) throws SQLException {
    
         ///////////////////////////////////////////////////////////////////////
         // NOTE: Copy the old row into the history table
         try (PreparedStatement stmt = conn.prepareStatement(
                 "INSERT INTO TEST_hist (testKey, MAINT_ACTION, MAINT_DATE_TIME, MAINT_USER) " +
                 "VALUES (?, ?, ?, ?)")
             ) {
                 stmt.setLong(1, (Long)oldRow[0]);
                 stmt.setString(2, (String)oldRow[1]);
                 stmt.setTimestamp(3, (Timestamp)oldRow[2]);
                 stmt.setString(4, (String)oldRow[3]);
    
                 stmt.executeUpdate();
             }
    
         ///////////////////////////////////////////////////////////////////////
         // NOTE: If the operation is a delete, then create a new entry for it
         //       in the history table too.
         if (((String)newRow[newRow.length-4]).equals("delete")) {
             try (PreparedStatement stmt = conn.prepareStatement(
                     "INSERT INTO TEST_hist (testKey, MAINT_ACTION, MAINT_DATE_TIME, MAINT_USER) " +
                     "VALUES (?, ?, ?, ?)")
                 ) {
                     stmt.setLong(1, (Long)newRow[0]);
                     stmt.setString(2, (String)newRow[1]);
                     stmt.setTimestamp(3, (Timestamp)newRow[2]);
                     stmt.setString(4, (String)newRow[3]);
    
                     stmt.executeUpdate();
                 }
    
             try (PreparedStatement stmt = conn.prepareStatement(
                     "DELETE FROM TEST " +
                     "WHERE id=?")
                 ) {
                     stmt.setLong(1, (Long)oldRow[0]);
                     stmt.executeUpdate();
                 }
    
         }
     }
    
     @Override
     public void close() throws SQLException {
         // TODO Auto-generated method stub
    
     }
    
     @Override
     public void remove() throws SQLException {
         // TODO Auto-generated method stub
    
     }
    
     public static Trigger create() {
         return new TriggerTest();
     }
    

    }

  2. Compiled my test trigger into a JAR file named Trigger.jar

  3. Start H2 database in server mode making sure to include my new jar file in the classpath (ie java -cp Trigger.jar -jar h2-1.4.200.jar -webAllowOthers -tcpAllowOthers)

  4. As a result of starting H2 in server mode, the console app is started in the browser. After I log into the console, I create tables named TEST and TEST_hist defined as follows

    CREATE TABLE TEST ( id INT AUTO_INCREMENT PRIMARY KEY, MAINT_ACTION ENUM('insert','update','delete'), MAINT_DATE_TIME Timestamp NOT NULL DEFAULT NOW(), MAINT_USER VARCHAR(250) NOT NULL );

    CREATE TABLE TEST_hist ( id INT AUTO_INCREMENT PRIMARY KEY, testKey INT NOT NULL, MAINT_ACTION ENUM('insert','update','delete'), MAINT_DATE_TIME Timestamp NOT NULL, MAINT_USER VARCHAR(250) NOT NULL );

  5. Create the Trigger in the console as follows:

    CREATE TRIGGER UPDATE_TEST AFTER UPDATE ON TEST FOR EACH ROW CALL "com.test.TriggerTest"

  6. When I run that command, I get the following error in the console window: Error creating or initializing trigger "UPDATE_TEST" object, class "com.test.TriggerTest", cause: "org.h2.message.DbException: Class ""com.test.TriggerTest"" not found [90086-200]"; see root cause for details; SQL statement: CREATE TRIGGER UPDATE_TEST AFTER UPDATE ON TEST FOR EACH ROW CALL "com.test.TriggerTest" [90043-200] 90043/90043 (Help)

So, I know the problem is that it can't find my class... But, I don't know why... I thought I was doing the right things by doing the steps above (ie adding my jar file to the classpath of the H2 server)

Where I have looked for answers: Everywhere on stackoverflow where answers seemed somewhat relevant, but didn't quite answer my question -- the following were the closest things I could find...

Plus, I looked at H2's site... https://www.h2database.com/html/commands.html#create_trigger

Please help and tia.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source