0

I could get notifications from an Oracle database thanks to this code and omitting this line:

prop.setProperty(OracleConnection.DCN_QUERY_CHANGE_NOTIFICATION,"true");

Also I could solve my ORA-29977 problem changing select * from act_code_metadata where product_id=1159 with select column_with_Number_type from act_code_metadata where product_id=1159

Everything works as expected :D

This is the code I use to print the row's information (Java 8):

DatabaseChangeRegistration dcp.addListener((DatabaseChangeEvent dce) -> 
                System.out.println(
                "Changed row id : " +
                dce.getTableChangeDescription()[0].getRowChangeDescription()[0].getRowid().stringValue() 
                + " " +  dce.getTableChangeDescription()[0].getRowChangeDescription()[0].getRowOperation().toString()));

But all the information I get is the row's physical address (rowid) and the operation involved (insert, delete or update). I need to identify the row being modified/inserted/deleted to refresh my cached data in several Swing controls in my GUI.

I've read that, despite the rowid being imutable, the same rowid can be re-assigned if the row is deleted and a new one is inserted, and the rowid can change if the row is in a partitioned table. So the best that can be done is using the rowid and the row's primary key. My table has a autoincrementable primary key (with a sequence and a trigger) created with this code.

I have no control on what happens on the database or if somebody inserts and deletes rows several times. So I can get the wrong row when selecting it using the rowid given by the notification.

Is there a way that I can get my row's primary key via Oracle Database Change Notification so I can identify the inserted/deleted/modified row correctly?

I'm working with Oracle Database XE 11.2 Express and Java 8. The user for database connection already has the change notification privilege.

Community
  • 1
  • 1
Broken_Window
  • 2,037
  • 3
  • 21
  • 47
  • Another case when you cannot trust rowid: if the table has "enable row movement" set; which is not likely, but possible. – Mark Stewart Mar 17 '16 at 02:49

1 Answers1

0

It seems that you have a lot of overhead trying to basically maintain a fresh snapshot of the data in your GUI. It may be simpler to look at client result caching and just re-running your query every X seconds; and let Oracle do the magic of seeing if the data changed. You would be limited to a JDBC driver that supports OCI. See http://docs.oracle.com/cd/E11882_01/server.112/e41573/memory.htm#PFGRF985 for details. With client result caching, the first time the SQL is executed, it will take say 500 milliseconds. Next query using the same criteria it will take 2 or 3 milliseconds. Assuming the result set is small (less than 100 rows is quite small), you can get a lot better results without all that framework you are trying to build.

Mark Stewart
  • 2,046
  • 4
  • 22
  • 32