Saturday, October 30, 2010

Upcoming Presentations at the Midwest Oracle Users Group

Just thought I would mention as I'm getting together my materials for my trip back to the windy city that I will be presenting next week at the Midwest Oracle Users Group annual conference on Friday, November 5th.

I'll be presenting the following:

  • SOA Integration & Application Development Framework: 8:15-9:15am
  • Oracle Fusion Development Platform: JDeveloper & ADF : 9:15-10:15am
  • RIAs and Web 2.0 made Simple: 1-2pm
If you happen to be in the Chicago area, you should attend and feel free to swing by and chat.

Creating a search page using the ADF Faces Rich Client Search Form context option

Okay, so like I said in my video on creating LOVs, I've gone ahead and made a follow-up video that actually demonstrates using the ADF Search Form context option that we used in the LOV demo as our form option. In this video, I take the view object that we created the LOV on and create a search page with a results section to highlight how easy it can be to do so using ADF.

I also refer to an example of creating a search page using a bind variable based view object that was pointed out to me by my friend Shay Shmeltzer. It is also an excellent sample, and when I was just reviewing it I had to chuckle because in my LOV demo writeup I referenced creating a af:selectOneChoice in the page designer rather than having it created and persisted on the actual View Object, Shays demo shows it, excellent! One thing to take note of though, is that the method he shows does not persist the LOV relationships that are formed when creating the page, they're only relevant for that particular page. So, if you dropped that same View Object (as we do in this search form demo) on another page you wouldn't get the LOV functionality that we get here.

Find my new video below:




So as you can see in the demo, the search form feature is a powerful, effective, and often overlooked feature in the ADF visual designer. The other thing you might have noticed is that when I showed how the controls on the execute button of the search form automatically registered the table as a partial target, there was another item registered there as well. That is because I had used the same data control to create a table on a separate tab on that same page. As a result, the button registered that table as a target as well.

This can be a nice benefit, or an unexpected behavior if you were to navigate around and suddenly a table on another part of the page that was previously displaying the full set of data from that data control was suddenly displaying a filtered set of data. There is nothing preventing you from taking the other tables off the partial target list for the search form, just be aware that the iterator containing the data under the covers has still been filtered by the actions of the search form.

If you want the data sets to be independent when you implement a search form off a data control that is used in other places; you can create an independent data control that is to be used just for the search form and results, or you would need to code a separate iterator for the data. The simpler option in my opinion would be to just use a redundant data control, but that's up to you.

Hope this provides some valuable information on an oft overlooked topic. I'm going to continue blogging on items that I come across while creating this sandbox application, but if anyone has any requests for topics feel free to email me at shaun.obrien@oracle.com and I'll see what I can do to whip something up...

Friday, October 29, 2010

Creating and Using LOVs (List of Values) in ADF Rich Client applications.

This is likely old hat to many of you but I dealt with a misconception on the forums that made me dig back into LOV creation and make sure that I had all my facts straight. As a result, I decided to just make a quick viewlet demonstrating how to create a LOV (List of Values) using ADF and the advantages to doing it ahead of time so that the framework recognizes it while doing its default binding activities. Check it out below:




So as you can see, they can be really helpful when you're dealing with pesky numerically based foreign keys in your data model. As I pointed out in the demo, it's also helpful if you can foresee the need for them ahead of time so you can create them on the relevant view objects before you drop them on the first page their needed on. That way the binding framework can automatically create the control as a LOV-based control instead of the standard input text forcing you to go back and change them once you get around to creating the LOV.

Of course you could do this manually without creating the LOV in the view object as well by dropping the attribute in question from the data control directly as an af:selectonechoice and completing the required information in the wizard similarly to what we did in the video.

Like I said at the end of the video, I'm going to also put together a viewlet showing how to use this same view object to demonstrate the usage of the ADF Search Form to speed the creation of search pages. Look for that in the next few days.

Thursday, October 28, 2010

Generating modeled database layout from JDeveloper

JDeveloper is a fantastic development tool that allows one to model and develop all layers of an application from the data all the way to the user interface and beyond. One of these awesome features is exposed via the database modeler. Here you can lay out everything pertaining to the data structure of your application prior to creating that structure in a database before actually generating it saving you the headache of repeatedly creating new DDL to make tweaks as you get it just right. Once you've done that you can then go on to generate the default data services that will fulfill the object side of the object-relational bridge of your application right from there as well!

In the database modeler you have options for everything you could think of: tables, views (materialized or not), constraints, keys, custom types, procedures, sequences, you name it. What was funny was I had one of those moments the other day when generating a data structure for a test application I have been working on that prompted my posting.

So anyway, I had modeled out my data structure, had my database connection set up and was ready to generate the modeled structure so I could begin working on creating my business components.

So here you can see the context menu used. I select what I want to create (in this case Ctrl-A for everything), and then right-click on the diagram selecting in the context menu: Synchronize with Database->Generate To->[database connection name].

I then jump midway into the generation wizard since I've already selected my source, target, and objects. I selected to create my objects (option of create, replace, and alter), opted not to create a script, and just told the wizard to finish. And, voila! Once I opened up the database navigator, there were my tables, all set up and ready to go for me. But here was the catch.

When you follow the steps I've just shown you, it creates the physical structure you designed but nothing else.

So for example, if you take a look here at one of the tables I created you will note that the primary key of the table, ID, is a sequence generated primary key that is populated by a BEFORE INSERT trigger. When I went to test data input with my newly created ADF business components I began getting errors because these weren't present. Luckily this was a simple problem to resolve.

All I had to do was to slide back over to my application navigator, highlight the sequences and triggers that I wanted (Ctrl-clicking my way down the list), and then right-click on them and select Generate To->[database connection name].

This then created the necessary sequences and triggers for me and life was grand. A simple thing, but something that was obviously easy to overlook even after doing it so many times. Luckily since I was using JDev I was able to identify, resolve, and verify my fix in less time than it took me to write this post!

Translating Display Values in ADF Rich Client LOVs


So I was working on a sample app I've been developing and came across an issue with getting a LOV to operate like I had expected it to. So, here is the db diagram of the tables involved. I have the standard ADF BC objects associated with this where I have the type table describing the various named types associated with the numerical id that is held in the TYPE_ID on the main component. So, on the MoveView I went ahead and created an LOV which defines the expected mapping of the ids of the TYPE_ID to the names described on the TYPE table.



So here you see the configuration of the LOV on the MoveView. Now, since the default UI hint is set as a choice list, if I just drop the view on a page it renders this by default as a selectOneChoice tag which is fine. However, if I go ahead and drop the attribute type_id directly from the data control palette I'm prompted with two options from the LOV context menu of ADF LOV Input or ADF LOV Choice List. The problem was introduced when I selected the ADF LOV Choice List. This creates as the rendering tag an "Input Combobox List of Values" which is bound to the LOV model as expected.






So here you can see the different renderings of those controls, both based on the LOV model. The problem I ran into with the control created by dragging the attribute directly from the data control palette is obvious. It lists the type names as desired instead of the type_id which is the actual table data, but once selected, the value that shows up in the collapsed control is the numerical backing value which isn't what I wanted. Thanks to Shays help we were able to come up with a simple (if perhaps not the ideal) workaround. We edited the MoveView, adding the Type table as a contributing entity and then added the name and id fields from the Type table as attributes of the MoveView. We then created a LOV definition on the newly included Name attribute.




So nothing really astonishing in creating this LOV. We then went and dropped the name attribute from the datacontrol palette to the page and dropped it as the aforementioned: "List of Values -> ADF LOV Choice List" which creates the InputComboboxListOfValues we saw before. We then went back into view object editor for the MoveView and made the TypeId attribute dependent on the Name attribute we just brought in from the Type entity. By doing this, when the Name attribute gets updated, the associated Type value will be applied. To tie this all together in the UI, we added the Name LOV control as a PartialTrigger on the TypeId control so that when we updated the Name, the TypeId control would also refresh with the appropriate data. This was mostly done for testing purposes as the Name control that we were creating was there to replace the need for the TypeId based control but we wanted to see that the associated TypeId value was indeed being set when the Name control was used. In the tests it worked perfectly! Thanks to Shay for his assistance getting this worked out.