'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:
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(); }}
Compiled my test trigger into a JAR file named Trigger.jar
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)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 );
Create the Trigger in the console as follows:
CREATE TRIGGER UPDATE_TEST AFTER UPDATE ON TEST FOR EACH ROW CALL "com.test.TriggerTest"
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 |
|---|
