I am implementing DCN to get notifications for records being inserted into a table. When I try inserting records, either within the application or with external scripts, it does not show the events in the console.
The next code is my implementation:
package co.app.dcn;
import oracle.jdbc.OracleConnection;
import oracle.jdbc.OracleDriver;
import oracle.jdbc.OracleStatement;
import oracle.jdbc.dcn.DatabaseChangeRegistration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
@Component
public class OracleDCNListener {
@Autowired
private JdbcTemplate jdbcTemplate;
@Value("${spring.datasource.username}")
private String DCN_USER;
@Value("${spring.datasource.password}")
private String DCN_PASSWORD;
@Value("${spring.datasource.url}")
private String DCN_URL;
@PostConstruct
public void initialize() throws SQLException {
var conn = connect();
var prop = new Properties();
prop.setProperty(OracleConnection.DCN_NOTIFY_ROWIDS, "true");
prop.setProperty(OracleConnection.DCN_QUERY_CHANGE_NOTIFICATION, "true");
DatabaseChangeRegistration dcr = conn.registerDatabaseChangeNotification(prop);
try {
DCNListener list = new DCNListener(this);
dcr.addListener(list);
// second step: add objects in the registration:
Statement stmt = conn.createStatement();
// associate the statement with the registration:
((OracleStatement) stmt).setDatabaseChangeRegistration(dcr);
ResultSet rs = stmt.executeQuery("SELECT * FROM CONTRATOS.CON_ESTADOS_PAGOS_CONTRATOS_NOTIFY");
String[] tableNames = dcr.getTables();
for (int i = 0; i < tableNames.length; i++)
System.out.println(tableNames[i] + " is part of the registration.");
rs.close();
stmt.close();
} catch (SQLException ex) {
if (conn != null)
conn.unregisterDatabaseChangeNotification(dcr);
throw ex;
} finally {
try {
// Note that we close the connection!
conn.close();
} catch (Exception innerex) {
innerex.printStackTrace();
}
}
synchronized (this) {
// The following code modifies the dept table and commits:
try {
OracleConnection conn2 = connect();
conn2.setAutoCommit(false);
Statement stmt2 = conn2.createStatement();
stmt2.executeUpdate("insert into contratos.CON_ESTADOS_PAGOS_CONTRATOS_NOTIFY (ID, ID_CLASE_DOCUMENTO, NUMERO_DOCUMENTO, OBSERVACIONES, ID_ESTADO, DESCRIPCION_ESTADO, FECHA_HORA_CREACION) values (99999920, 0, 0, ' ', 0, ' ', ' ')",
Statement.RETURN_GENERATED_KEYS);
ResultSet autoGeneratedKey = stmt2.getGeneratedKeys();
if (autoGeneratedKey.next())
System.out.println("inserted one row with ROWID=" + autoGeneratedKey.getString(1));
stmt2.executeUpdate("insert into contratos.CON_ESTADOS_PAGOS_CONTRATOS_NOTIFY (ID, ID_CLASE_DOCUMENTO, NUMERO_DOCUMENTO, OBSERVACIONES, ID_ESTADO, DESCRIPCION_ESTADO, FECHA_HORA_CREACION) values (99999922, 0, 0, ' ', 0, ' ', ' ')",
Statement.RETURN_GENERATED_KEYS);
autoGeneratedKey = stmt2.getGeneratedKeys();
if (autoGeneratedKey.next())
System.out.println("inserted one row with ROWID=" + autoGeneratedKey.getString(1));
stmt2.close();
conn2.commit();
conn2.close();
} catch (SQLException ex) {
ex.printStackTrace();
}
// wait until we get the event
try {
this.wait();
} catch (InterruptedException ie) {
}
}
// At the end: close the registration (comment out these 3 lines in order
// to leave the registration open).
//OracleConnection conn3 = connect();
//conn3.unregisterDatabaseChangeNotification(dcr);
//conn3.close();
}
OracleConnection connect() throws SQLException {
OracleDriver dr = new OracleDriver();
Properties prop = new Properties();
prop.setProperty("user", DCN_USER);
prop.setProperty("password", DCN_PASSWORD);
return (OracleConnection) dr.connect(DCN_URL, prop);
}
}
package co.app.dcn;
import oracle.jdbc.dcn.DatabaseChangeEvent;
import oracle.jdbc.dcn.DatabaseChangeListener;
public class DCNListener implements DatabaseChangeListener {
OracleDCNListener oracleDCNListener;
public DCNListener(OracleDCNListener oracleDCNListener) {
this.oracleDCNListener = oracleDCNListener;
}
public void onDatabaseChangeNotification(DatabaseChangeEvent e)
{
Thread t = Thread.currentThread();
System.out.println("DCNDemoListener: got an event ("+this+" running on thread "+t+")");
System.out.println(e.toString());
synchronized( oracleDCNListener ){ oracleDCNListener.notify();}
}
}
I already checked SELECT * FROM USER_CHANGE_NOTIFICATION_REGS and yes the records of the registration are being created.
New contributor
Santiago is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.