I'm attempting to register change notifications from Oracle tables (19c) using Oracle JDBC . Since the query contains a JOIN I'm using BEST effort mode. My user has been "granted" CHANGE NOTIFICATION rights.
At this point I'm just trying to get the notifier accept any query. This is not the final version but I do know that we'll need a query that involves two tables with a join.
Changing the query to something simpler like SELECT * from SCDAT.SECURITIES WHERE SCDAT.SECURITIES.INSTYPE = 28
gives the same output.
Test code
log.info("init changelistener");
log.info("Get datasource from Spring application context");
oracleDataSource = context.getBean("dataSource", OracleDataSource.class);
log.info("Cet Oracle connection from datasource");
oracle.jdbc.OracleConnection connection = (OracleConnection) oracleDataSource.getConnection();
Properties properties = new Properties();
properties.setProperty(OracleConnection.DCN_NOTIFY_ROWIDS, "true");
properties.setProperty(OracleConnection.DCN_QUERY_CHANGE_NOTIFICATION, "true");
properties.setProperty(OracleConnection.DCN_BEST_EFFORT, "true");
log.info("DCN property settings: {}", properties);
log.info("Register change notification to connection");
dcr = connection.registerDatabaseChangeNotification(properties);
//create statement
Statement stmt = connection.createStatement();
// associate the statement with the registration:
((OracleStatement) stmt).setDatabaseChangeRegistration(dcr);
log.info("Executing query {}", query);
ResultSet rs = stmt.executeQuery(query);
while (rs.next()) {
// Do Nothing
}
log.info("attach listener to the processor");
dcr.addListener(this);
String[] tableNames = dcr.getTables();
for (int i = 0; i < tableNames.length; i++)
log.info(tableNames[i] + " is part of the registration.");
Log output
2021-03-30 12:56:15.983 INFO 5180 --- [main] c.c.dbnotifier.OracleChangeListener : init changelistener
2021-03-30 12:56:15.983 INFO 5180 --- [main] c.c.dbnotifier.OracleChangeListener : Get datasource from Spring application context
2021-03-30 12:56:15.983 INFO 5180 --- [main] c.c.dbnotifier.OracleChangeListener : Cet Oracle connection from datasource
2021-03-30 12:56:16.061 INFO 5180 --- [main] c.c.dbnotifier.OracleChangeListener : DCN property settings: {DCN_QUERY_CHANGE_NOTIFICATION=true, DCN_BEST_EFFORT=true, DCN_NOTIFY_ROWIDS=true}
2021-03-30 12:56:16.061 INFO 5180 --- [main] c.c.dbnotifier.OracleChangeListener : Register change notification to connection
2021-03-30 12:56:16.077 INFO 5180 --- [main] c.c.dbnotifier.OracleChangeListener : Executing query SELECT SCDAT.TRANSMAIN.TRANSEX from SCDAT.TRANSMAIN,SCDAT.SECURITIES WHERE SCDAT.TRANSMAIN.SECIK = SCDAT.SECURITIES.SECIK AND SCDAT.SECURITIES.INSTYPE = 28
2021-03-30 12:56:16.295 WARN 5180 --- [main] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'oracleChangeListener': Invocation of init method failed; nested exception is java.sql.SQLException: ORA-29979: ikke støttet radstørrelse for endringsvarsling for spørringsresultat
The error ORA-29979 is explained here https://www.oraexcel.com/database-oracle-11gR2-ORA-29979 but the COMPATIBLE setting is 19.0.0 on the database according to dbadmin.
I should add that running the queries in sqldeveloper with same user works fine.
Any suggestions or ideas on how to proceed?
/Katarina
You will have to switch to "table change notification" because your table has too many columns to support "query change notification". Remove this line or comment it out:
// properties.setProperty(OracleConnection.DCN_QUERY_CHANGE_NOTIFICATION, "true");