My name is Shaun O'Brien and I'm a Principal Product Manager of Development Tools for Oracle Corporation.
I spend a lot of my time focusing on customers both from an evangelism standpoint and also to gather requirements. I try to understand what is needed from the JDeveloper and ADF platforms and then take that back to the organization and help make it a reality.
I also help out with in-house development efforts. It is good to know that by the time a release of JDev rolls out that it has been hammered on for months by actual devs here that are producing apps that directly impact Oracles bottom line. As such, when something comes up about the tool or framework that is not quite right we have a huge lever to pull to get the appropriate effort to "make it right".
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 email@example.com and I'll see what I can do to whip something up...
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.
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!
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.
For those of you who have followed my blog regularly, you know that I have always been into working with new and exciting hardware and seeing what I can do with it utilizing the Oracle product stack. From my first simple web server installation to host our first web site, to the full sized rack packed with enterprise hardware (SUN E450s, E420s, dell blades, load balancer, etc).
Well, I've moved in a new direction. Short of getting Oracle to lend me an Exadata machine I don't think I can go much further in the "big iron" direction, so interestingly I've been pointed in the "portable power" direction. I'm looking for the most power I can pack in a small package.
So, after reading through a bunch of reviews I settled on a boutique hardware builder named "Maingear" located out of New Jersey. Going on their site reminded me of any of the major hardware organizations with one exception, instead of having a never-ending list of different chassis selections, they focused on a select list of machines, and when it came to component selection, even the least expensive machines utilized name brand components (Intel, AMD, ATI, etc).
I ended up selecting their x-cube chassis as we are looking for portable power, this is an interesting small form factor chassis but I ended up being able to load it with components that would normally be in a full sized chassis. I had the option of loading it with 16gb of ram, the Intel i7 quad-core processors, dual 2tb drives in a RAID configuration, a bevy of video cards, and a lovely 1KW power supply to make sure all these components have the juice they need.
After I made the heart-wrenching decisions on what to take and what to cut, I placed my order. Usually, that would be where most new machine experiences would stop until it arrived, but Maingear has been unreal with their customer support. I have actually been able to speak with the person that is going to be building my machine! On top of that, I have been in a bit of a time crunch and their customer service has been something that I can't even describe.
As a quote from one of my email exchanges with a Maingear team member reads: "As a smaller company, we still have that “passion” for perfection, competitive spirit and belief in customer satisfaction".
If the machine itself gets half the attention that I have gotten as the customer, I can't wait to open it up and see what it can do when I load the Fusion stack on it.