Update/Insert With ADF Web Service Data Control

The Web service data control (WSDC) in ADF is a powerful feature that allows you to easily build a UI on top of WS interfaces exposed by other systems.

However when you drag a WSDC to a page you usually get a set of output components where the data is shown. So how would you actually do an update operation on those values?
The answer is that you need a call to another method in your WSDC that does the update - but what if you want to pass to it the actual values that you get from the get method you invoked before?

Here is a demo showing how to do that:

The two tricks that are shown here are:
Changing the properties of items in the DC to be updateable - this gives you inputText fields instead of outputText fields.
And passing the currentRow.dataProvider to the update method (and choosing the right iterator for this).

Comments:

Hi Shay, Thanks for blogging as to how we can do insert/update using WS data control. However my use case is as follows: Data is shown in a read only list. User is provided with Create & Edit buttons. Upon "Create", a blank free form is to be displayed in a popup where in user can key in information and hit "Save". This will close the popup and then refresh the list to display the newly added record. Alternatively user can select a record in the table and click "Edit". In this case the selected record is displayed in free form in popup where he can update the information and save. Can we achieve both Insert & Update in declarative manner ? Please suggest optimum way of handling this requirement. Thanks Navin

Posted by Navin on June 02, 2010 at 02:47 AM PDT #

Navin, It should be quite straightforward to take the approach I've shown and just place the insert/update inside a pop-up components in your ADF Faces page.

Posted by shay.shmeltzer on June 03, 2010 at 07:27 AM PDT #

Shay, The information is GREAT! I have tried this in my web application with Peoplesoft, but get error. Do the parameters of 'Update' method must match the return fields in 'Get' method? Thank you, Jeff

Posted by Jeff on September 16, 2010 at 05:02 AM PDT #

To work in this way you need the same object from the get and the set. However you can also do some tricks to map it to different objects. See this blog entry for how to set parameters: http://blogs.oracle.com/shay/2009/07/java_class_data_control_and_ad.html

Posted by shay.shmeltzer on September 16, 2010 at 05:30 AM PDT #

I can't see anything...

Posted by Cruyhyn on October 11, 2010 at 10:59 PM PDT #

It's a youtube video - make sure you have flash installed - or look for it on my channel on youtube - youtube.com/user/shayjdev

Posted by shay.shmeltzer on October 12, 2010 at 12:15 AM PDT #

hi shayne, thanks for this vid. I just have few questions regarding my application. It almost the same as yours,except that the getEmployee part is triggered once the view button is hit (thus upon load of page, no value is displayed yet)... So, there's an input text,wherein user should key-in the employee id. then clicking the View button, it should call the data control, passing the input text value... after calling the web service, it should return values in a table.. I followed the video,however, the table values is not being reflected on the page (or i think,even the input text value is not being passed to the data control). can you suggest what should i tweak in my components? thanks!

Posted by cosmoghurl on November 18, 2010 at 10:56 AM PST #

cosmoghurl, you can delay the execution of a method that depends on a parameter as shown here: http://blogs.oracle.com/shay/2010/08/delay_method_execution_when_us.html

Posted by shay.shmeltzer on November 22, 2010 at 03:33 AM PST #

Shay, Thanks for blogging. My requirement is to insert data into two databases using two different webservices. But the information should be inserted using a single button not two adf buttons. Any help on how to acheive this would be great. thanks!

Posted by Pri on February 14, 2011 at 08:03 PM PST #

Pri - check out this entry to see how you can invoke two operations from one button: http://blogs.oracle.com/shay/2010/04/doing_two_declarative_operatio.html

Posted by shay.shmeltzer on February 15, 2011 at 02:18 AM PST #

Video is not displayed even after installing latest flash player. Kindly check it.

Posted by Kartick on February 24, 2011 at 06:31 PM PST #

You can see the demo directly on my YouTube channel: http://www.youtube.com/watch?v=XF18vXxYkxM

Posted by shay.shmeltzer on February 25, 2011 at 03:04 AM PST #

Hi Shay,

Nice blog.
I am getting a issue while creating a data control based on WSDL.
I am getting Create Data Control Failed Dialog and it Says

DCA-29000: Unexpected exception caught:
java.lang.NullPointerException, msg=null

Is it happening because of WSDL or something else?

Regards
Thoom

Posted by Thoom on July 01, 2011 at 03:32 AM PDT #

Thoom, hard to say if the problem is in the WSDL or in the data control wizard. One thing you can try is creating a Java Proxy for the Web service and see if that one works or if you get a more meaningful error message. If that doesn't work I would suggest contacting Oracle Support.

Posted by Shay on July 01, 2011 at 03:58 AM PDT #

Shay,

Thanks for reply.
I am able to create java proxy with webservice. No error while creating that.

Issue is coming only when i try to create DataControl using webservice.

Regards
Thoom

Posted by Thoom on July 01, 2011 at 04:05 AM PDT #

Thoom - if the Web service proxy work you can just create a data control from the Java proxy class.
You can also contact support and open a bug against the Web service data control providing the specific WSDL that doesn't work for you.

Posted by Shay on July 01, 2011 at 04:10 AM PDT #

Hi Shay
Thanks for all the great tips, you've been very helpful. I'm now trying to do exactly what you've demonstrated here but can't get it to work. Trying to use a web service generated by the Oracle EBS SOA Gateway which by default creates "SOAHeader" and "body" message parts for the service "update" operation call signature. Within the "body" is another complex data structure (called "CONTRACT_ITEM") containing 14 attributes. These are the same 14 attributes returned by the get operation which are also nested within a complex data structure. By default, ADF creates a "CONTRACTS_ITEMIterator" when I drop the data structure from within the Return of the data control "get" operation onto a form. I specify this same iterator for the binding (#{bindings.CONTRACTS_ITEMIterator.currentRow.dataProvider}) of my "body" message part in my "update" operation. However, the EBS SOA Monitor indicates I'm passing a null request (no data in input "body") whenever I invoke the "update" operation. I created a backing bean for my update action so I could set a breakpoint and evaluate #{bindings.CONTRACTS_ITEMIterator.currentRow.dataProvider} with the EL evaluator tool just before the operation binding is executed and it looks just fine (not null, all the correct data). What does look interesting is the console output from the IntegratedWebLogicServer displays the following message whenever I run the page:
"<MessagePart> <checkComplexPrototype> Complex type 'body' cannot be supported"

Any thoughts would be greatly appreciated.
Thanks,
Tom

Posted by guest on October 04, 2011 at 03:56 AM PDT #

Tom, one thing to try is to use a Java proxy class that calls the Web service. Your Java class can provide a simpler structure for getting parameters and then construct the complex object that you pass to the Web service. Then you can expose that proxy class as a data control and try to invoke that simplified method from your JSF page.

Posted by Shay on October 05, 2011 at 03:51 AM PDT #

Hi Shay,
Thanks for the tip on using the web service java proxy class - it works well. It looks like the best approach is to use 2 different data controls: One that is created from the WSDL for "get" or "read" operations and one that is created from a proxy class based on the WSDL for "update" or "write" operations. The drag and drop functionality for creating UI components from the data control return data has some issues when using the proxy-based control - the binding becomes very confusing. I think it's related to the fact that the complex data structures created by the web service proxy wizard are all based on the JAXBElement<> class. What is nice is that if you use HashMap as the type for the input argument on the "update" proxy method, you can bind the data control method directly to the return iterator for the complex data type you are updating using the visual binding editor.

Thanks again,
Tom

Posted by TomW on October 12, 2011 at 02:41 AM PDT #

Hi Shay,
Well explained. In my application i am trying to do update and insert operations using url service datacontrols as the application is available as a restful web service. When i am creating the url service datacontrol I selected the http method as POST and giving the servicepath and servicename as the source. After providing the xsd's path and all , when I test the url connection, I am getting the following error message:
URL Test: Received Error: Method Not Allowed

Now under the data controls navigator, If i view the newly created data control, i could see the loadData(Object) method which i assume is for retrieving the data from the service. But since i have mentioned the method as POST, why such a method is created? Also if its there, can I use the same for insert and update? Under the data control property inspector, i changed the supportsupdate attribute's value to true. But when i am trying to save the employee from the jspx page, I am getting the following message in the integrated weblogic's log
Couldn't get access to the data source. Cause Unsupported Media Type exception in rest service

And on the server side I am getting the following error message:

No message body reader has been found for request class Employee, ContentType application/octet-stream.

My intention is to to send the xml request for inserting the new record

For that, i have mentioned the xsd document while creating the data control

I have read that url service dc is a nonupdateable data control.Does it means that we cannot use this data control for update or insert? If we can, what should be the approach? If we can't , then whats the workaround for this?

Thanks,
Rampal

Posted by Rampal on January 17, 2012 at 10:39 PM PST #

Rampal, if you are using 11.1.2 then we have new support for REST services through the URL Data control - see this tutorial:
http://docs.oracle.com/cd/E18941_01/tutorials/jdtut_11r2_53/jdtut_11r2_53.html

Posted by Shay on January 18, 2012 at 03:58 AM PST #

Hi Shay,
Thanks for the wonderful explanations.

I am actually facing a problem in updating the data using ADF.
In that am using a wsdl created in PeopleSoft for a component called emergency data.

The wsdl shows four services-get, find, update and update data.
Find and get operations are working fine with the adf but problem is coming up with Update Data where I am trying to update the existing data using UD operation.

Note: All the services in WSDL are working fine from PeopleSoft.I had ensured this by using Service Operation Tester in PeopleSoft. I gave a Sample input XML file to the respective service Operation testers in PeopleSoft and it worked fine (Even Update Data service operation worked fine).

In my page ,on my left side I have put employeeid as a parameter from get and with a button (get object).By providing the employee id and clicking this get button I am able to see the employee data on the right side(which i have accomplished by taking the return values of get and creating a table out of it on right side).

Now I have an update button (created from 'Update data' object) to update the data. I chose the iterator name as- variable which i dragged as a result on right side of page to display result,with Iterator as its suffix.

But when I am clicking the update button, It does not update the data.Neither it is showing any error.
Could you please let me know what could go wrong in this? If you want screenshots I can send you. Thanks so much for all the information you have provided

Regards,
Aritra

Posted by aritra on February 06, 2012 at 09:21 PM PST #

Aritra, these type of questions might be better discussed on the JDeveloper OTN Forum.
In general I would recommend you first try and drag over the update method as a parameter form - and make sure it works.
Only then merge it with the query method.

Posted by Shay on February 07, 2012 at 10:42 AM PST #

Hi mate - nice discussion and commentary.

We're trying to use declarative WS Data Controls and Task Flows in WebCenter Spaces via Mash-ups, and are experiencing similar issues to that originally described.

In our case we create a WS Data Control in Spaces / Resources against a WS exposing 1 service with 2 operations; get and update.

We then create a Task Flow in Spaces / Resources with 1 form that holds the results of a parameterised call to the the get operation, and another which has an updateable form that sends data to the update operation. We want to prepopulate the 2nd form with the values in the 1st form, but no matter what we do we can't seem to get around the fact that when we bind the inputText fields in the 2nd form to fields in the 1st they automatically turn readonly. We don't have field-level access to the Data Control to set fields to be updateable. Any ideas?

Posted by Dennis Remmer on May 23, 2012 at 05:54 AM PDT #

Dennis - you should probably post this question on the JDeveloper discussion forum.
You should clarify why you don't have access to the fields to set them to be updateable.
Also - you might want to see if using a Java proxy class that talks to the Web service and then exposing that class as a data control will yield better results.

Posted by shay on May 23, 2012 at 10:31 AM PDT #

Hi I was watching at your posts but with no luck about any help with a problem I got. I have a page with many tabs but each tab has its own method executed, the problem is that if I load all methods at beggining it takes a lot of time, so I execute each method when tab is disclosed. But when its a table I want to fill values wich comes from an string array in the binding the data is not displayed. But if I execute all the methods at the beginning the data is displayed.

The way Im assigning values on tables is:
<af:table value="#{binding.arrayp}" var="row" varStatus="status" id="t1" >
<af:column sortable="false" headerText="Date" id="c4">
<af:outputText value="#{binding.arrayp[status.index][0]}" id="ot45"/>
</af:column>
<af:column sortable="false" headerText="Name1" id="c2">
<af:outputText value="#{binding.arrayp[status.index][1]}" id="ot44"/>
</af:column>
<af:column sortable="false" headerText="Description" id="c3">
<af:outputText value="#{binding.arrayp[status.index][2]}" id="ot43"/>
</af:column>
<af:column sortable="false" headerText="Amount" id="c5">
<af:outputText value="#{binding.arrayp[status.index][3]}" id="ot47"/>
</af:column>
<af:column sortable="false" headerText="Type" id="c1">
<af:outputText value="#{binding.arrayp[status.index][4]}" id="ot46"/>
</af:column>
</af:table>

The bindings are going through PageDef which has refresh condition as #{binding.tabDE.disclosed eq "true"} for each tab.

And on my binding.java I have the bindings from the tabs and the methods that update the data I'm passing to the table:

public void setTabDE(RichShowDetailItem tabDE) {
this.tabDE = tabDE;
}

public RichShowDetailItem getTabDE() {
return tabDE;
}

Thanks for any help you could bring.

Posted by Jennifer Martinez on October 25, 2012 at 09:05 AM PDT #

Jennifer, I can't really debug your code from here - I would suggest running with the ADF Debugger and checking to see if the parameter you are using actually has the value it needs to have to fetch the data.
Might be an issue with the scope of the bean you are using to pass the value.
More on the ADF Debugger here:
https://blogs.oracle.com/shay/entry/introduction_to_the_adf_debugger

Posted by Shay on October 26, 2012 at 09:05 AM PDT #

Hi Shay,

Thanks for the post, realy helpful

I could not turn the field to updatable.

I am using JDevelopper 11g Release 2, I do not seem to have the same output in the structure window when selecting return.xml.

I tried to update the the property by opening the Return.xml (I have a property called "Updatable" and it is to Allways).

Is this related to the JDeveloper version? if so how is it done in the Release 2?

Thanks

Lamine

Posted by Lamine on December 14, 2013 at 07:23 AM PST #

Post a Comment:
  • HTML Syntax: NOT allowed
About

me
I'm a Director of Product Management for the Oracle Java Development Tools.
Follow me:
Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today