I am performing an upsert operation using PostgreSQL 11.6 Table using WSO2 DSS in WSO2 EI 6.4.0
Table Data:
dev_source dev_id dev_name
cloud Cloud Device
amazon ec2 Ec2
solaris 4737 Web
where dev_id is primary key
DSS- Code:
<data name="WSO2_test_DSS" transports="http https local">
<config enableOData="false" id="ZCloudDataSource">
<property name="driverClassName">org.postgresql.Driver</property>
<property name="url">jdbc:postgresql://postgreurl:5432/test_schema</property>
<property name="username">username</property>
<property name="password">password</property>
</config>
<query id="dev_insert_Q" returnUpdatedRowCount="true" useConfig="ZCloudDataSource">
<sql>insert into zcloudtest.dev_test (dev_source,dev_id,dev_name) values(?,?,?) ON CONFLICT (dev_id) DO UPDATE SET (dev_source,dev_name)=(excluded.dev_source,excluded.dev_name)</sql>
<result element="UpdatedRowCount" rowName="" useColumnNumbers="true">
<element column="1" name="Value" xsdType="integer"/>
</result>
<param name="dev_source" sqlType="STRING"/>
<param name="dev_id" sqlType="STRING"/>
<param name="dev_name" sqlType="STRING"/>
</query>
<operation name="dev_insert_op">
<call-query href="dev_insert_Q">
<with-param name="dev_source" query-param="tenant"/>
<with-param name="dev_id" query-param="source"/>
<with-param name="dev_name" query-param="device_id"/>
</call-query>
</operation>
</data>
I need to upsert the data rather than plain insert. So used ON CONFLICT (dev_id) DO UPDATE SET feature mentioned here in query to achieve the same.
Even though added above ON CONFLICT to query, It is below mentioned throwing ERROR.
ERROR Log:
[2023-03-20 11:33:36,610] [-1234] [] [PassThroughMessageProcessor-42] ERROR {org.wso2.carbon.dataservices.core.DBInOutMessageReceiver} - Error in in-out message receiver
DS Code: DATABASE_ERROR
Nested Exception:-
javax.xml.stream.XMLStreamException: DS Fault Message: Error in 'SQLQuery.processPreNormalQuery': ERROR: duplicate key value violates unique constraint "dev_test_pkey"
Detail: Key (dev_id)=(Cloud) already exists.
DS Code: DATABASE_ERROR
Source Data Service:-
Name: WSO2_test_DSS
Location: /home/wso2carbon/wso2ei-6.4.0/wso2/tmp/carbonapps/-1234/test-ETL_CAR_1.0.0-SNAPSHOT.car/WSO2_test_DSS_1.0.0/WSO2_test_DSS-1.0.0.dbs
Description: N/A
Default Namespace: http://ws.wso2.org/dataservice
Current Request Name: device_inventory_insert_op
Current Params: {dev_name=Device, dev_id=Cloud, dev_source=Cloud}
Nested Exception:-
org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "dev_test_pkey"
Detail: Key (dev_id)=(Cloud) already exists.
at org.wso2.carbon.dataservices.core.dispatch.SingleDataServiceRequest.processRequest(SingleDataServiceRequest.java:75)
at org.wso2.carbon.dataservices.core.dispatch.DataServiceRequest.dispatch(DataServiceRequest.java:359)
at org.wso2.carbon.dataservices.core.DataServiceProcessor.dispatch(DataServiceProcessor.java:41)
at org.wso2.carbon.dataservices.core.DBInOutMessageReceiver.invokeBusinessLogic(DBInOutMessageReceiver.java:57)
at org.apache.axis2.receivers.AbstractInOutSyncMessageReceiver.invokeBusinessLogic(AbstractInOutSyncMessageReceiver.java:42)
at org.apache.axis2.receivers.AbstractMessageReceiver.receive(AbstractMessageReceiver.java:110)
at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:180)
at org.apache.synapse.transport.passthru.ServerWorker.processNonEntityEnclosingRESTHandler(ServerWorker.java:337)
at org.apache.synapse.transport.passthru.ServerWorker.processEntityEnclosingRequest(ServerWorker.java:383)
at org.apache.synapse.transport.passthru.ServerWorker.run(ServerWorker.java:151)
at org.apache.axis2.transport.base.threads.NativeWorkerPool$1.run(NativeWorkerPool.java:172)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: javax.xml.stream.XMLStreamException: DS Fault Message: Error in 'SQLQuery.processPreNormalQuery': ERROR: duplicate key value violates unique constraint "dev_test_pkey"
Detail: Key (dev_id)=(Cloud) already exists.
DS Code: DATABASE_ERROR
Source Data Service:-
Name: WSO2_test_DSS
Location: /home/wso2carbon/wso2ei-6.4.0/wso2/tmp/carbonapps/-1234/test-ETL_CAR_1.0.0-SNAPSHOT.car/WSO2_test_DSS_1.0.0/WSO2_test_DSS-1.0.0.dbs
Description: N/A
Default Namespace: http://ws.wso2.org/dataservice
Current Request Name: device_inventory_insert_op
Current Params: {dev_name=Device, dev_id=Cloud, dev_source=Cloud}
Nested Exception:-
org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "dev_test_pkey"
Detail: Key (dev_id)=(Cloud) already exists.
at org.wso2.carbon.dataservices.core.engine.DSOMDataSource.execute(DSOMDataSource.java:102)
at org.wso2.carbon.dataservices.core.dispatch.SingleDataServiceRequest.processRequest(SingleDataServiceRequest.java:73)
... 13 more
The same Sort of ERROR I've got when used plain insert query, so modified query with ON CONFLICT to do upsert operation. Still it throws ERROR? This means ON CONFLICT not working in DSS?
PS: Insert query with ON CONFLICT is working fine in workbench and updated row in table