Tutorial: Learn how to implement data change notifications in the Oracle Database! 🤔
Receiving database change notifications is a powerful concept when it comes to software development and relational database dev projects and in this tutorial, we’ll explore an Oracle database change notification (Oracle DCN) Java code example.
Oracle Change Notification TOC
Oracle Continuous Query Notification (Oracle CQN) is a real-time event notification feature in the Oracle Database (see also: the Oracle Database page on Wikipedia) that allows applications to receive immediate notifications when defined relational database modifications take place, enabling timely responses as well as push-based data synchronization.
In this instructional, we’ll detail the steps required to configure Oracle change notification events via the JDBC driver.
This article was updated on May 27, 2025 — note that this guide also appears as an advanced example in the Introduction to Java article.
Preconditions to running the Oracle change notification Java example
The following two gists are required preconditions for this example.
It is important to note that Docker was running on another machine which, in this case, uses the Ubuntu operating system.
See the warning regarding running Oracle in Docker locally in the DatabaseChangeListenerInOracleDatabaseExample.groovy script for complete details (find the gist on GitHub).
#
# In this example Docker is running on another machine so assume that I've ssh'd into that box and
# am running the following on the remote machine.
#
docker run -d -p 1521:1521 oracleinanutshell/oracle-xe-11g
docker exec -it [container id] /bin/sh
su
#
# Username: system, password: oracle
#
/u01/app/oracle/product/11.2.0/xe/bin/sqlplus
In SQL*Plus, we can now run the following configuration script.
Keep in mind that once the example table has been created, see line #8, the Groovy script in the next section can be started and any insert, update, or delete operations on the target table will result in an event being sent to the Groovy script and then printed to the console output (find the gist on GitHub).
--
-- This is required otherwise notifications won't be sent to the JDBC driver.
--
grant change notification to system;
commit;
CREATE TABLE example(
example_id NUMBER(10) PRIMARY KEY,
phrase VARCHAR2(120) NOT NULL
);
commit;
insert into example values (1, 'one');
insert into example values (2, 'two');
insert into example values (3, 'three');
insert into example values (4, 'four');
insert into example values (5, 'five');
commit;
--
-- Then once the DatabaseChangeListenerInOracleDatabaseExample.groovy is running
-- execute the following and an update should appear in the Groovy console:
--
update example set phrase = 'one / 1' where example_id = 1;
In the next section we’ll explore the steps required to code an Oracle change notification example in the Java programming language (see also: the Java programming language page on Wikipedia).
How to implement the DatabaseChangeListener Java Example callback
Here we’ll provide step-by-step instructions for implementing the oracle.jdbc.dcn.DatabaseChangeListener callback using the Groovy scripting language, which extends the Java programming language and comes in handy for building and running short examples, like what we have here.
Step One: Implement Preconditions
For this example, we’ll need to include the com.oracle.database.jdbc ojdbc6 dependency version 11.2.0.4.
If you run this example via the groovyConsole and Groovy Grape should be able to pull in the dependency without any additional steps required.
Step Two: Import the required classes
We need to import the Oracle DatabaseChangeListener callback along with other supporting classes required to run this example.
import oracle.jdbc.dcn.DatabaseChangeListener
import oracle.jdbc.dcn.DatabaseChangeEvent
import oracle.jdbc.driver.OracleConnection
import oracle.jdbc.dcn.DatabaseChangeRegistration
import oracle.jdbc.OracleStatement
import java.sql.DriverManager
import java.util.Properties
Step Three: Get a connection to the Oracle Database using the Oracle JDBC driver manager
We need to get a connection from the Oracle JDBC driver manager — in this example, the endpoint we’re using is running locally in Docker.
final def connection = DriverManager.getConnection("jdbc:oracle:thin:@192.168.1.232:1521:xe", "system", "oracle")
Step Four: Get an instance of DatabaseChangeRegistration
We need to set some properties and then get an instance of DatabaseChangeRegistration from the connection to the Oracle relational database.
databaseProperties.setProperty(OracleConnection.DCN_NOTIFY_ROWIDS, "true")
databaseProperties.setProperty(OracleConnection.DCN_QUERY_CHANGE_NOTIFICATION, "true")
final def databaseChangeRegistration = connection.registerDatabaseChangeNotification(databaseProperties)
Step Five: Implement the Oracle DatabaseChangeListener interface.
Implement the Oracle oracle.jdbc.dcn.DatabaseChangeListener interface.
In this example, we’re simply printing out some of the information included in the oracle.jdbc.dcn.DataChangeEvent parameter, as is demonstrated below.
public class ExampleDatabaseChangeListener implements DatabaseChangeListener {
@Override
public void onDatabaseChangeNotification(DatabaseChangeEvent databaseChangeEvent) {
println ("***** databaseChangeEvent: $databaseChangeEvent")
println ("***** databaseChangeEvent.source: ${databaseChangeEvent.source}")
println ("***** databaseChangeEvent.queryChangeDescription: ${databaseChangeEvent.queryChangeDescription}")
println ("***** databaseChangeEvent.tableChangeDescription: ${databaseChangeEvent.tableChangeDescription.each {println '\n - nextTableChangeDescription: $it' } }")
}
}
Step Six: Register a new instance of the example DatabaseChanceListener with the instance of DatabaseChangeRegistration.
In this step we need to register a new instance of the ExampleDatabaseChangeListener, which is an instance of oracle.jdbc.dcn.DatabaseChangeListener with the instance of oracle.jdbc.dcn.DatabaseChangeRegistration.
databaseChangeRegistration.addListener(new ExampleDatabaseChangeListener ())
Step Seven: Assign the DatabaseChangeRegistration instance to the statement
We need to create a statement and then register a new instance of DatabaseChangeRegistration with that statement by calling the setDatabaseChangeRegistration method.
final def statement = connection.createStatement()
statement.setDatabaseChangeRegistration(databaseChangeRegistration)
Oracle Database Change Notification Full Example
Here we have an example of the complete DatabaseChangeListenerInOracleDatabaseExample.groovy script.
Groovy is an excellent scripting language that extends the Java programming language and we’ll try to stay close to Java as our approach to building out the code below.
Note that the developer must implement one method:
void onDatabaseChangeNotification(DatabaseChangeEvent databaseChangeEvent)
We can see this implementation on line #55 below (find the gist on GitHub).
@GrabConfig(systemClassLoader=true)
@Grapes(
@Grab(group='com.oracle.database.jdbc', module='ojdbc6', version='11.2.0.4')
)
import oracle.jdbc.dcn.DatabaseChangeListener
import oracle.jdbc.dcn.DatabaseChangeEvent
import oracle.jdbc.driver.OracleConnection
import oracle.jdbc.dcn.DatabaseChangeRegistration
import oracle.jdbc.OracleStatement
import java.sql.DriverManager
import java.util.Properties
final def connection = DriverManager.getConnection("jdbc:oracle:thin:@192.168.1.232:1521:xe", "system", "oracle")
def databaseProperties = new Properties ()
databaseProperties.setProperty(OracleConnection.DCN_NOTIFY_ROWIDS, "true")
databaseProperties.setProperty(OracleConnection.DCN_QUERY_CHANGE_NOTIFICATION, "true")
final def databaseChangeRegistration = connection.registerDatabaseChangeNotification(databaseProperties)
public class ExampleDatabaseChangeListener implements DatabaseChangeListener {
@Override
public void onDatabaseChangeNotification(DatabaseChangeEvent databaseChangeEvent) {
println ("***** databaseChangeEvent: $databaseChangeEvent")
println ("***** databaseChangeEvent.source: ${databaseChangeEvent.source}")
println ("***** databaseChangeEvent.queryChangeDescription: ${databaseChangeEvent.queryChangeDescription}")
println ("***** databaseChangeEvent.tableChangeDescription: ${databaseChangeEvent.tableChangeDescription.each {println '\n - nextTableChangeDescription: $it' } }")
}
}
databaseChangeRegistration.addListener(new ExampleDatabaseChangeListener ())
final def statement = connection.createStatement()
statement.setDatabaseChangeRegistration(databaseChangeRegistration)
try {
resultSet = statement.executeQuery("select * from example")
while (resultSet.next())
{} // println "resultSet.phrase: ${resultSet.getString('phrase')}"
} catch (Throwable thrown) {
thrown.printStackTrace (System.err)
}
println "databaseChangeRegistration.userName: ${databaseChangeRegistration.userName}"
databaseChangeRegistration.tables.each {
println "tables: $it"
}
final def time = 60 * 60 * 1000
println "Will sleep for $time milliseconds..."
try {
Thread.sleep (time)
} catch (Throwable thrown) {
thrown.printStackTrace (System.err)
} finally {
statement.close ()
connection.close ()
}
println "...done!"
The following image goes into deeper detail regarding what each step is doing, along with some notes explaining the output.
Lastly, the following image demonstrates that when we perform five inserts in a row and then commit the changes, only a single event is emitted, which includes these five inserts. Events are only ever emitted whenever a commit has returned successfully.
In the next section we’ll take a look at some of the details regarding custom callback handling as it pertains to the oracle.jdbc.dcn.DatabaseChangeListener interface.
Custom callback handling with the oracle.jdbc.dcn.DatabaseChangeListener specification
The oracle.jdbc.dcn.DatabaseChangeListener callback specification is an interface defined in the Oracle JDBC (Java Database Connectivity) library used in Java applications to implement database change notification functionality in the Oracle Database.
Key components when implementing custom callback handling include:
Oracle Database Change Notification (DCN)
Oracle Database Change Notification feature allows applications to receive real-time notifications when certain database events or changes in the database take place.
These events include data modifications such as insert, update, and delete operations, changes in database objects, or other specified events.
Oracle Database Change Notification Callback
In the context of the Oracle JDBC library, the oracle.jdbc.dcn.DatabaseChangeListener is a Java interface provided by Oracle.
The DatabaseChangeListener specification serves as a blueprint for creating callback objects that can be registered with the relational database to handle change notifications.
Software engineers can implement this interface and define custom logic that will execute when a database change event takes place.
The DatabaseChangeListener specification contains a single method, onDatabaseChangeNotification, that must be implemented by the developer to handle specific database change events.
When a registered change event matches the conditions set by the application, the corresponding callback method is invoked, allowing the application to respond to the event in a custom way.
In summary, the oracle.jdbc.dcn.DatabaseChangeListener callback is part of the Oracle JDBC library and is used to implement custom callback logic for handling Oracle Database Change Notification events.
Software developers create classes that implement this interface to define how their Java applications should respond to real-time database changes.
The DatabaseChangeListener callback allows applications to stay updated and take immediate action when relevant database events occur.
Tutorial Conclusion
In conclusion, Oracle Database change notification updates offer a powerful way to monitor database changes in real time, improving efficiency and enabling proactive responses to critical updates.
Intercepting Oracle DCN events can help to optimize database management as well as streamline operations across enterprise environments.
Learn more about database change notifications — a hidden gem supported by some relational databases.
See Also
- This guide covers an H2 Trigger Example.
- The tutorial that reviews an H2 Database Spring Boot example provides guidance regarding how to how to do this in several steps and includes a complete example too.
- The article covers various options available to implement MySQL listen notify functionality for real-time database change notifications.
- A complete example regarding intercepting Postgres notifications can be found in this guide.











